<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[2146] 2013/sayaksarkar: Added Basic App Structure with Compose module.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://gsoc.trac.wordpress.org/changeset/2146">2146</a></dd>
<dt>Author</dt> <dd>sayaksarkar</dd>
<dt>Date</dt> <dd>2013-07-23 16:49:28 +0000 (Tue, 23 Jul 2013)</dd>
</dl>
<h3>Log Message</h3>
<pre>Added Basic App Structure with Compose module.</pre>
<h3>Added Paths</h3>
<ul>
<li>2013/sayaksarkar/branches/</li>
<li>2013/sayaksarkar/tags/</li>
<li>2013/sayaksarkar/trunk/</li>
<li><a href="#2013sayaksarkartrunkREADMEmd">2013/sayaksarkar/trunk/README.md</a></li>
<li>2013/sayaksarkar/trunk/enyo/</li>
<li><a href="#2013sayaksarkartrunkenyoCONTRIBUTINGmd">2013/sayaksarkar/trunk/enyo/CONTRIBUTING md</a></li>
<li><a href="#2013sayaksarkartrunkenyoLICENSE20txt">2013/sayaksarkar/trunk/enyo/LICENSE-2.0.txt</a></li>
<li><a href="#2013sayaksarkartrunkenyoREADMEmd">2013/sayaksarkar/trunk/enyo/README.md</a></li>
<li><a href="#2013sayaksarkartrunkenyoenyojs">2013/sayaksarkar/trunk/enyo/enyo.js</a></li>
<li><a href="#2013sayaksarkartrunkenyoloaderjs">2013/sayaksarkar/trunk/enyo/loader.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/minify/</li>
<li><a href="#2013sayaksarkartrunkenyominifyminifybat">2013/sayaksarkar/trunk/enyo/minify/minify.bat</a></li>
<li><a href="#2013sayaksarkartrunkenyominifyminifysh">2013/sayaksarkar/trunk/enyo/minify/minify.sh</a></li>
<li><a href="#2013sayaksarkartrunkenyominifypackagejs">2013/sayaksarkar/trunk/enyo/minify/package.js</a></li>
<li><a href="#2013sayaksarkartrunkenyopackagejson">2013/sayaksarkar/trunk/enyo/package.json</a></li>
<li>2013/sayaksarkar/trunk/enyo/samples/</li>
<li><a href="#2013sayaksarkartrunkenyosamplesAjaxSamplecss">2013/sayaksarkar/trunk/enyo/samples/AjaxSample.css</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesAjaxSamplehtml">2013/sayaksarkar/trunk/enyo/samples/AjaxSample.html</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesAjaxSamplejs">2013/sayaksarkar/trunk/enyo/samples/AjaxSample.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesGestureSamplecss">2013/sayaksarkar/trunk/enyo/samples/GestureSample.css</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesGestureSamplehtml">2013/sayaksarkar/trunk/enyo/samples/GestureSample.html</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesGestureSamplejs">2013/sayaksarkar/trunk/enyo/samples/GestureSample.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesJsonpSamplecss">2013/sayaksarkar/trunk/enyo/samples/JsonpSample.css</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesJsonpSamplehtml">2013/sayaksarkar/trunk/enyo/samples/JsonpSample.html</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesJsonpSamplejs">2013/sayaksarkar/trunk/enyo/samples/JsonpSample.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesPlatformSamplecss">2013/sayaksarkar/trunk/enyo/samples/PlatformSample.css</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesPlatformSamplehtml">2013/sayaksarkar/trunk/enyo/samples/PlatformSample.html</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesPlatformSamplejs">2013/sayaksarkar/trunk/enyo/samples/PlatformSample.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesPlaygroundcss">2013/sayaksarkar/trunk/enyo/samples/Playground.css</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesPlaygroundhtml">2013/sayaksarkar/trunk/enyo/samples/Playground.html</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesPlaygroundjs">2013/sayaksarkar/trunk/enyo/samples/Playground.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesRepeaterSamplecss">2013/sayaksarkar/trunk/enyo/samples/RepeaterSample.css</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesRepeaterSamplehtml">2013/sayaksarkar/trunk/enyo/samples/RepeaterSample.html</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesRepeaterSamplejs">2013/sayaksarkar/trunk/enyo/samples/RepeaterSample.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesScrollerSamplecss">2013/sayaksarkar/trunk/enyo/samples/ScrollerSample.css</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesScrollerSamplehtml">2013/sayaksarkar/trunk/enyo/samples/ScrollerSample.html</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesScrollerSamplejs">2013/sayaksarkar/trunk/enyo/samples/ScrollerSample.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesWebServiceSamplecss">2013/sayaksarkar/trunk/enyo/samples/WebServiceSample.css</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesWebServiceSamplehtml">2013/sayaksarkar/trunk/enyo/samples/WebServiceSample.html</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesWebServiceSamplejs">2013/sayaksarkar/trunk/enyo/samples/WebServiceSample.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/samples/assets/</li>
<li><a href="#2013sayaksarkartrunkenyosamplesassetsSample1js">2013/sayaksarkar/trunk/enyo/samples/assets/Sample1.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesassetsSample2js">2013/sayaksarkar/trunk/enyo/samples/assets/Sample2.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesassetsSample3js">2013/sayaksarkar/trunk/enyo/samples/assets/Sample3.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplesassetsSample4js">2013/sayaksarkar/trunk/enyo/samples/assets/Sample4.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosamplespackagejs">2013/sayaksarkar/trunk/enyo/samples/package.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/source/</li>
<li>2013/sayaksarkar/trunk/enyo/source/ajax/</li>
<li><a href="#2013sayaksarkartrunkenyosourceajaxAjaxjs">2013/sayaksarkar/trunk/enyo/source/ajax/Ajax.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceajaxAjaxPropertiesjs">2013/sayaksarkar/trunk/enyo/source/ajax/AjaxProperties.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceajaxAsyncjs">2013/sayaksarkar/trunk/enyo/source/ajax/Async.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceajaxJsonpjs">2013/sayaksarkar/trunk/enyo/source/ajax/Jsonp.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceajaxWebServicejs">2013/sayaksarkar/trunk/enyo/source/ajax/WebService.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceajaxcookiejs">2013/sayaksarkar/trunk/enyo/source/ajax/cookie.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceajaxformdatajs">2013/sayaksarkar/trunk/enyo/source/ajax/formdata.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceajaxjsonjs">2013/sayaksarkar/trunk/enyo/source/ajax/json.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceajaxpackagejs">2013/sayaksarkar/trunk/enyo/source/ajax/package.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceajaxxhrjs">2013/sayaksarkar/trunk/enyo/source/ajax/xhr.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/source/boot/</li>
<li><a href="#2013sayaksarkartrunkenyosourcebootbootjs">2013/sayaksarkar/trunk/enyo/source/boot/boot.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcebootenyojs">2013/sayaksarkar/trunk/enyo/source/boot/enyo.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcebootpackagejs">2013/sayaksarkar/trunk/enyo/source/boot/package.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/source/dom/</li>
<li><a href="#2013sayaksarkartrunkenyosourcedomControljs">2013/sayaksarkar/trunk/enyo/source/dom/Control.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedomanimationjs">2013/sayaksarkar/trunk/enyo/source/dom/animation.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedomdispatcherjs">2013/sayaksarkar/trunk/enyo/source/dom/dispatcher.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedomdomcss">2013/sayaksarkar/trunk/enyo/source/dom/dom.css</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedomdomjs">2013/sayaksarkar/trunk/enyo/source/dom/dom.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedomdragjs">2013/sayaksarkar/trunk/enyo/source/dom/drag.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedomgesturejs">2013/sayaksarkar/trunk/enyo/source/dom/gesture.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedommodaljs">2013/sayaksarkar/trunk/enyo/source/dom/modal.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedompackagejs">2013/sayaksarkar/trunk/enyo/source/dom/package.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedomphonegapjs">2013/sayaksarkar/trunk/enyo/source/dom/phonegap.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedomplatformjs">2013/sayaksarkar/trunk/enyo/source/dom/platform.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedompreviewjs">2013/sayaksarkar/trunk/enyo/source/dom/preview.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedomtransformjs">2013/sayaksarkar/trunk/enyo/source/dom/transform.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcedomtransitionjs">2013/sayaksarkar/trunk/enyo/source/dom/transition.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/source/kernel/</li>
<li><a href="#2013sayaksarkartrunkenyosourcekernelComponentjs">2013/sayaksarkar/trunk/enyo/source/kernel/Component.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcekernelLayoutjs">2013/sayaksarkar/trunk/enyo/source/kernel/Layout.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcekernelObjectjs">2013/sayaksarkar/trunk/enyo/source/kernel/Object.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcekernelOopjs">2013/sayaksarkar/trunk/enyo/source/kernel/Oop.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcekernelSignalsjs">2013/sayaksarkar/trunk/enyo/source/kernel/Signals.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcekernelUiComponentjs">2013/sayaksarkar/trunk/enyo/source/kernel/UiComponent.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcekerneljobjs">2013/sayaksarkar/trunk/enyo/source/kernel/job.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcekernellangjs">2013/sayaksarkar/trunk/enyo/source/kernel/lang.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcekernellogjs">2013/sayaksarkar/trunk/enyo/source/kernel/log.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcekernelmacroizejs">2013/sayaksarkar/trunk/enyo/source/kernel/macroize.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcekernelpackagejs">2013/sayaksarkar/trunk/enyo/source/kernel/package.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcepackagejs">2013/sayaksarkar/trunk/enyo/source/package.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/source/touch/</li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchScrollMathjs">2013/sayaksarkar/trunk/enyo/source/touch/ScrollMath.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchScrollStrategyjs">2013/sayaksarkar/trunk/enyo/source/touch/ScrollStrategy.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchScrollercss">2013/sayaksarkar/trunk/enyo/source/touch/Scroller.css</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchScrollerjs">2013/sayaksarkar/trunk/enyo/source/touch/Scroller.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchThumbcss">2013/sayaksarkar/trunk/enyo/source/touch/Thumb.css</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchThumbjs">2013/sayaksarkar/trunk/enyo/source/touch/Thumb.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchTouchScrollStrategyjs">2013/sayaksarkar/trunk/enyo/source/touch/TouchScrollStrategy.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchTransitionScrollStrategyjs">2013/sayaksarkar/trunk/enyo/source/touch/TransitionScrollStrategy.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchTranslateScrollStrategyjs">2013/sayaksarkar/trunk/enyo/source/touch/TranslateScrollStrategy.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchgesturejs">2013/sayaksarkar/trunk/enyo/source/touch/gesture.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchmseventsjs">2013/sayaksarkar/trunk/enyo/source/touch/msevents.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchpackagejs">2013/sayaksarkar/trunk/enyo/source/touch/package.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourcetouchtouchjs">2013/sayaksarkar/trunk/enyo/source/touch/touch.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/source/ui/</li>
<li><a href="#2013sayaksarkartrunkenyosourceuiAnimatorjs">2013/sayaksarkar/trunk/enyo/source/ui/Animator.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiBaseLayoutjs">2013/sayaksarkar/trunk/enyo/source/ui/BaseLayout.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiButtonjs">2013/sayaksarkar/trunk/enyo/source/ui/Button.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiCheckboxjs">2013/sayaksarkar/trunk/enyo/source/ui/Checkbox.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiDragAvatarjs">2013/sayaksarkar/trunk/enyo/source/ui/DragAvatar.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiFloatingLayerjs">2013/sayaksarkar/trunk/enyo/source/ui/FloatingLayer.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiGroupjs">2013/sayaksarkar/trunk/enyo/source/ui/Group.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiGroupItemjs">2013/sayaksarkar/trunk/enyo/source/ui/GroupItem.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiImagejs">2013/sayaksarkar/trunk/enyo/source/ui/Image.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiInputjs">2013/sayaksarkar/trunk/enyo/source/ui/Input.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiPopupjs">2013/sayaksarkar/trunk/enyo/source/ui/Popup.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiRepeaterjs">2013/sayaksarkar/trunk/enyo/source/ui/Repeater.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiRichTextjs">2013/sayaksarkar/trunk/enyo/source/ui/RichText.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiSelectjs">2013/sayaksarkar/trunk/enyo/source/ui/Select.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiSelectionjs">2013/sayaksarkar/trunk/enyo/source/ui/Selection.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiTextAreajs">2013/sayaksarkar/trunk/enyo/source/ui/TextArea.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiToolDecoratorjs">2013/sayaksarkar/trunk/enyo/source/ui/ToolDecorator.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuipackagejs">2013/sayaksarkar/trunk/enyo/source/ui/package.js</a></li>
<li><a href="#2013sayaksarkartrunkenyosourceuiuicss">2013/sayaksarkar/trunk/enyo/source/ui/ui.css</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsREADMEmd">2013/sayaksarkar/trunk/enyo/tools/README.md</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsdeployjs">2013/sayaksarkar/trunk/enyo/tools/deploy.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolslesscbat">2013/sayaksarkar/trunk/enyo/tools/lessc.bat</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolslesscsh">2013/sayaksarkar/trunk/enyo/tools/lessc.sh</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifierlesscjs">2013/sayaksarkar/trunk/enyo/tools/minifier/lessc.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifierminifyjs">2013/sayaksarkar/trunk/enyo/tools/minifier/minify.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessCHANGELOGmd">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/CHANGELOG.md</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessLICENSE">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/LICENSE</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessMakefile">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/Makefile</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessREADMEmd">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/README.md</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/benchmark/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbenchmarkbenchmarkless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/benchmark/benchmark.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbenchmarklessbenchmarkjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/benchmark/less-benchmark.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/bin/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbinlessc">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/bin/lessc</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbuildamdjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/amd.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbuildecma5js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/ecma-5.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbuildheaderjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/header.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbuildrequirerhinojs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/require-rhino.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbuildrequirejs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/require.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless110js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.0.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless110minjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.0.min.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless111js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.1.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless111minjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.1.min.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless112js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.2.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless112minjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.2.min.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless113js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.3.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless113minjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.3.min.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless114js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.4.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless114minjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.4.min.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless115js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.5.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless115minjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.5.min.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless116js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.6.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless116minjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.6.min.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless120js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.0.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless120minjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.0.min.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless121js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.1.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless121minjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.1.min.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless122js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.2.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless122minjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.2.min.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless130js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless130minjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0.min.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless130ejs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0e.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless130eminjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0e.min.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistlessrhino113js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-rhino-1.1.3.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistlessrhino115js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-rhino-1.1.5.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblessbrowserjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/browser.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesscolorsjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/colors.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesscssminjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/cssmin.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblessfunctionsjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/functions.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblessindexjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/index.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesslessc_helperjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/lessc_helper.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblessparserjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/parser.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblessrhinojs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/rhino.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreealphajs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/alpha.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeanonymousjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/anonymous.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeassignmentjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/assignment.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreecalljs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/call.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreecolorjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/color.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreecommentjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/comment.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeconditionjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/condition.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreedimensionjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/dimension.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreedirectivejs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/directive.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeelementjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/element.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeexpressionjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/expression.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeimportjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/import.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreejavascriptjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/javascript.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreekeywordjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/keyword.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreemediajs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/media.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreemixinjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/mixin.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeoperationjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/operation.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeparenjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/paren.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreequotedjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/quoted.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeratiojs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/ratio.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreerulejs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/rule.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreerulesetjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/ruleset.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeselectorjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/selector.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeurljs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/url.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreevaluejs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/value.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreevariablejs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/variable.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreejs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesspackagejson">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/package.json</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsscolorscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/colors.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsscommentscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/comments.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsscss3css">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/css-3.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsscssescapescss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/css-escapes.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsscsscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/css.css</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssdebuglinenumbersallcss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/linenumbers-all.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssdebuglinenumberscommentscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/linenumbers-comments.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssdebuglinenumbersmediaquerycss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/linenumbers-mediaquery.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssfunctionscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/functions.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssiefilterscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/ie-filters.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssimportoncecss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/import-once.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssimportcss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/import.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssjavascriptcss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/javascript.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsslazyevalcss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/lazy-eval.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmediacss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/media.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinsargscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-args.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinsclosurecss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-closure.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinsguardscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-guards.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinsimportantcss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-important.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinsnamedargscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-named-args.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinsnestedcss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-nested.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinspatterncss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-pattern.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssoperationscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/operations.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssparenscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/parens.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssrulesetscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/rulesets.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssscopecss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/scope.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssselectorscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/selectors.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssstringscss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/strings.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssvariablescss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/variables.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsswhitespacecss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/whitespace.css</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesscolorsless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/colors.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesscommentsless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/comments.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesscss3less">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/css-3.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesscssescapesless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/css-escapes.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesscssless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/css.less</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/debug/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/debug/import/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessdebugimporttestless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/debug/import/test.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessdebuglinenumbersless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/debug/linenumbers.less</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorscommentinselectorless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/comment-in-selector.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorscommentinselectortxt">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/comment-in-selector.txt</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportmissingless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-missing.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportmissingtxt">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-missing.txt</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportnosemiless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-no-semi.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportnosemitxt">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-no-semi.txt</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportsubfolder1less">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder1.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportsubfolder1txt">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder1.txt</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportsubfolder2less">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder2.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportsubfolder2txt">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder2.txt</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportsimportsubfolder1less">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/import-subfolder1.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportsimportsubfolder2less">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/import-subfolder2.less</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/subfolder/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportssubfoldermixinnotdefinedless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/subfolder/mixin-not-defined.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportssubfolderparseerrorcurlybracketless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/subfolder/parse-error-curly-bracket.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsjavascripterrorless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/javascript-error.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsjavascripterrortxt">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/javascript-error.txt</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsmixinnotdefinedless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/mixin-not-defined.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsmixinnotdefinedtxt">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/mixin-not-defined.txt</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsparseerrorcurlybracketless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-curly-bracket.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsparseerrorcurlybrackettxt">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-curly-bracket.txt</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsparseerrormissingbracketless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-missing-bracket.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsparseerrormissingbrackettxt">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-missing-bracket.txt</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorspropertyie5hackless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/property-ie5-hack.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorspropertyie5hacktxt">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/property-ie5-hack.txt</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessfunctionsless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/functions.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessiefiltersless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/ie-filters.less</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/deeper/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportdeeperimportoncetestaless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/deeper/import-once-test-a.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportimportoncetestcless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-once-test-c.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportimporttestaless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-a.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportimporttestbless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-b.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportimporttestcless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-c.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportimporttestdcss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-d.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportimporttesteless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-e.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportonceless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import-once.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessjavascriptless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/javascript.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesslazyevalless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/lazy-eval.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmedialess">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/media.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsargsless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-args.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsclosureless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-closure.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsguardsless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-guards.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsimportantless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-important.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsnamedargsless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-named-args.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsnestedless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-nested.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinspatternless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-pattern.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessoperationsless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/operations.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessparensless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/parens.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessrulesetsless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/rulesets.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessscopeless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/scope.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessselectorsless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/selectors.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessstringsless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/strings.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessvariablesless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/variables.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesswhitespaceless">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/whitespace.less</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesstestjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less-test.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjsnpmignore">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/.npmignore</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjsREADMEhtml">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/README.html</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjsREADMEorg">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/README.org</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/bin/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjsbinuglifyjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/bin/uglifyjs</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjsdocstylecss">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/docstyle.css</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjslibconsolidatorjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/consolidator.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjslibparsejsjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/parse-js.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjslibprocessjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/process.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjslibsqueezemorejs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/squeeze-more.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjspackagejson">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/package.json</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestbeautifyjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/beautify.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstesttestparserjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/testparser.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedarray1js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array1.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedarray2js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array2.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedarray3js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array3.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedarray4js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array4.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedassignmentjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/assignment.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedconcatstringjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/concatstring.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedconstjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/const.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedemptyblocksjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/empty-blocks.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedforstatementjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/forstatement.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedifjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/if.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedifreturnjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/ifreturn.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedifreturn2js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/ifreturn2.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue10js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue10.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue11js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue11.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue13js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue13.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue14js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue14.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue16js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue16.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue17js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue17.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue20js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue20.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue21js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue21.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue25js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue25.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue27js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue27.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue278js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue278.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue28js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue28.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue29js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue29.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue30js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue30.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue34js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue34.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue4js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue4.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue48js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue48.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue50js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue50.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue53js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue53.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue541js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue54.1.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue68js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue68.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue69js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue69.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue9js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue9.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedmanglejs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/mangle.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectednull_stringjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/null_string.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedstrictequalsjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/strict-equals.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedvarjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/var.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedwhitespacejs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/whitespace.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedwithjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/with.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestarray1js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array1.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestarray2js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array2.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestarray3js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array3.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestarray4js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array4.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestassignmentjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/assignment.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestconcatstringjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/concatstring.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestconstjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/const.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestemptyblocksjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/empty-blocks.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestforstatementjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/forstatement.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestifjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/if.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestifreturnjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/ifreturn.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestifreturn2js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/ifreturn2.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue10js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue10.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue11js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue11.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue13js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue13.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue14js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue14.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue16js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue16.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue17js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue17.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue20js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue20.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue21js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue21.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue25js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue25.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue27js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue27.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue278js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue278.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue28js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue28.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue29js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue29.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue30js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue30.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue34js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue34.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue4js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue4.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue48js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue48.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue50js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue50.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue53js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue53.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue541js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue54.1.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue68js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue68.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue69js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue69.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue9js">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue9.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestmanglejs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/mangle.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestnull_stringjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/null_string.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressteststrictequalsjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/strict-equals.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestvarjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/var.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestwhitespacejs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/whitespace.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestwithjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/with.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitscriptsjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/scripts.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstmphoistjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/hoist.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstmpinstrumentjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/instrument.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstmptestjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/test.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjsuglifyjsjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/uglify-js.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifiernode_moduleswalkerjs">2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/walker.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifierpathrelativeshimjs">2013/sayaksarkar/trunk/enyo/tools/minifier/path-relative-shim.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifybat">2013/sayaksarkar/trunk/enyo/tools/minify.bat</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsminifysh">2013/sayaksarkar/trunk/enyo/tools/minify.sh</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/.bin/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesbinnopt">2013/sayaksarkar/trunk/enyo/tools/node_modules/.bin/nopt</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesbinshjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/.bin/shjs</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesnoptnpmignore">2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/.npmignore</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesnoptLICENSE">2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/LICENSE</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesnoptREADMEmd">2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/README.md</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/bin/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesnoptbinnoptjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/bin/nopt.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/examples/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesnoptexamplesmyprogramjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/examples/my-program.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/lib/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesnoptlibnoptjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/lib/nopt.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesnoptnode_modulesabbrevREADMEmd">2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/README.md</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/lib/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesnoptnode_modulesabbrevlibabbrevjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/lib/abbrev.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesnoptnode_modulesabbrevpackagejson">2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/package.json</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesnoptpackagejson">2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/package.json</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljsdocumentupjson">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/.documentup.json</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstravisyml">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/.travis.yml</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljsLICENSE">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/LICENSE</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljsREADMEmd">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/README.md</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/bin/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljsbinshjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/bin/shjs</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljsglobaljs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/global.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljsmakejs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/make.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljspackagejson">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/package.json</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/scripts/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljsscriptsdocsjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/scripts/docs.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljsscriptsruntestsjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/scripts/run-tests.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljsshelljs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/shell.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestnpmignore">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/.npmignore</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestcatjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/cat.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestcdjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/cd.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestcpjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/cp.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestechojs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/echo.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestenvjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/env.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestexecjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/exec.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestfindjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/find.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestgrepjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/grep.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestlsjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/ls.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestmkdirjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/mkdir.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestmvjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/mv.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestpwdjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/pwd.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesatxt">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/a.txt</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcescpa">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/a</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcescpb">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/b</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/dir_a/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcescpdir_az">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/dir_a/z</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/dir_b/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/dir_b/dir_b_a/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/dir_b/dir_b_a/dir_b_a_a/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcescpdir_bdir_b_adir_b_a_az">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/dir_b/dir_b_a/dir_b_a_a/z</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesexternalnode_scriptjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/node_script.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/tmp/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesexternaltmpoutput">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/tmp/output</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesexternaltmptempscriptjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/tmp/tempscript.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfile1">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file1</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfile1js">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file1.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfile1txt">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file1.txt</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfile2">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file2</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfile2js">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file2.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfile2txt">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file2.txt</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfindhidden">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/.hidden</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfinda">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/a</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfindb">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/b</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir1/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfinddir1a_dir1">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir1/a_dir1</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir1/dir11/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfinddir1dir11a_dir11">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir1/dir11/a_dir11</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir2/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfinddir2a_dir1">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir2/a_dir1</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/.hidden_dir/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslshidden_dirnada">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/.hidden_dir/nada</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslshidden_file">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/.hidden_file</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/.hidden_dir/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsa_dirhidden_dirnada">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/.hidden_dir/nada</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/b_dir/</li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsa_dirb_dirz">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/b_dir/z</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsa_dirnada">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/nada</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsfile1">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file1</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsfile1js">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file1.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsfile2">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file2</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsfile2js">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file2.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsfilenamewithcharsthatmustbeescaped">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/filename(with)[chars$]^that.must+be-escaped</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestrmjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/rm.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestsedjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/sed.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestsilentjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/silent.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstesttempdirjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/tempdir.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstesttestjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/test.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstesttojs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/to.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolsnode_modulesshelljstestwhichjs">2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/which.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/test/</li>
<li>2013/sayaksarkar/trunk/enyo/tools/test/ajax/</li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxindexhtml">2013/sayaksarkar/trunk/enyo/tools/test/ajax/index.html</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxpackagejs">2013/sayaksarkar/trunk/enyo/tools/test/ajax/package.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/</li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxphpredballjpg">2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/redball.jpg</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxphptest1php">2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test1.php</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxphptest2php">2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test2.php</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxphptest3php">2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test3.php</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxphptest4php">2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test4.php</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxphptest5php">2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test5.php</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxphptest6php">2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test6.php</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/</li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxtestsAjaxTestjs">2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/AjaxTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxtestsJsonpTestjs">2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/JsonpTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxtestsWebServiceTestjs">2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/WebServiceTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxtestsXhrTestjs">2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/XhrTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestajaxtestspackagejs">2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/package.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/test/core/</li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoreindexhtml">2013/sayaksarkar/trunk/enyo/tools/test/core/index.html</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestcss">2013/sayaksarkar/trunk/enyo/tools/test/core/test.css</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/test.js</a></li>
<li>2013/sayaksarkar/trunk/enyo/tools/test/core/tests/</li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsAjaxTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/AjaxTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsAsyncTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/AsyncTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsComponentDispatchTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ComponentDispatchTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsComponentHandlersTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ComponentHandlersTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsComponentTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ComponentTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsControlPropsTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ControlPropsTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsControlTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ControlTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsDecodePackagePathTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/DecodePackagePathTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsJsonTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/JsonTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsKindTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/KindTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsLoaderTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/LoaderTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsPathResolverTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/PathResolverTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsViewportPositioningTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ViewportPositioningTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestslangTestjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/langTest.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsloader1js">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/loader1.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsloader2ajs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/loader2a.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestsloader2bjs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/loader2b.js</a></li>
<li><a href="#2013sayaksarkartrunkenyotoolstestcoretestspackagejs">2013/sayaksarkar/trunk/enyo/tools/test/core/tests/package.js</a></li>
<li><a href="#2013sayaksarkartrunkiconpng">2013/sayaksarkar/trunk/icon.png</a></li>
<li>2013/sayaksarkar/trunk/images/</li>
<li>2013/sayaksarkar/trunk/images/compose/</li>
<li><a href="#2013sayaksarkartrunkimagescomposeicon_bquotepng">2013/sayaksarkar/trunk/images/compose/icon_bquote.png</a></li>
<li><a href="#2013sayaksarkartrunkimagescomposeicon_camerapng">2013/sayaksarkar/trunk/images/compose/icon_camera.png</a></li>
<li><a href="#2013sayaksarkartrunkimagescomposeicon_centerpng">2013/sayaksarkar/trunk/images/compose/icon_center.png</a></li>
<li><a href="#2013sayaksarkartrunkimagescomposeicon_leftpng">2013/sayaksarkar/trunk/images/compose/icon_left.png</a></li>
<li><a href="#2013sayaksarkartrunkimagescomposeicon_linkpng">2013/sayaksarkar/trunk/images/compose/icon_link.png</a></li>
<li><a href="#2013sayaksarkartrunkimagescomposeicon_morepng">2013/sayaksarkar/trunk/images/compose/icon_more.png</a></li>
<li><a href="#2013sayaksarkartrunkimagescomposeicon_olpng">2013/sayaksarkar/trunk/images/compose/icon_ol.png</a></li>
<li><a href="#2013sayaksarkartrunkimagescomposeicon_rightpng">2013/sayaksarkar/trunk/images/compose/icon_right.png</a></li>
<li><a href="#2013sayaksarkartrunkimagescomposeicon_ulpng">2013/sayaksarkar/trunk/images/compose/icon_ul.png</a></li>
<li><a href="#2013sayaksarkartrunkimagesfaviconpng">2013/sayaksarkar/trunk/images/favicon.png</a></li>
<li><a href="#2013sayaksarkartrunkimagesicon128png">2013/sayaksarkar/trunk/images/icon128.png</a></li>
<li><a href="#2013sayaksarkartrunkimagesicon30png">2013/sayaksarkar/trunk/images/icon30.png</a></li>
<li><a href="#2013sayaksarkartrunkimagesicon48png">2013/sayaksarkar/trunk/images/icon48.png</a></li>
<li><a href="#2013sayaksarkartrunkimagesicon60png">2013/sayaksarkar/trunk/images/icon60.png</a></li>
<li><a href="#2013sayaksarkartrunkimagesicon64png">2013/sayaksarkar/trunk/images/icon64.png</a></li>
<li>2013/sayaksarkar/trunk/images/toolbar/</li>
<li><a href="#2013sayaksarkartrunkimagestoolbarbackpng">2013/sayaksarkar/trunk/images/toolbar/back.png</a></li>
<li><a href="#2013sayaksarkartrunkimagestoolbardrawerpng">2013/sayaksarkar/trunk/images/toolbar/drawer.png</a></li>
<li><a href="#2013sayaksarkartrunkimagestoolbarnewpng">2013/sayaksarkar/trunk/images/toolbar/new.png</a></li>
<li><a href="#2013sayaksarkartrunkimagestoolbarrefreshpng">2013/sayaksarkar/trunk/images/toolbar/refresh.png</a></li>
<li><a href="#2013sayaksarkartrunkimagestoolbarwppng">2013/sayaksarkar/trunk/images/toolbar/wp.png</a></li>
<li><a href="#2013sayaksarkartrunkindexhtml">2013/sayaksarkar/trunk/index.html</a></li>
<li>2013/sayaksarkar/trunk/lib/</li>
<li>2013/sayaksarkar/trunk/lib/layout/</li>
<li><a href="#2013sayaksarkartrunkliblayoutCONTRIBUTINGmd">2013/sayaksarkar/trunk/lib/layout/CONTRIBUTING md</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutREADMEmd">2013/sayaksarkar/trunk/lib/layout/README.md</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutdeploybat">2013/sayaksarkar/trunk/lib/layout/deploy.bat</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutdeploysh">2013/sayaksarkar/trunk/lib/layout/deploy.sh</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutdesignjs">2013/sayaksarkar/trunk/lib/layout/design.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/fittable/</li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablepackagejs">2013/sayaksarkar/trunk/lib/layout/fittable/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/fittable/samples/</li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout1html">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout1.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout1js">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout1.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout2html">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout2.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout2js">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout2.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout3html">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout3.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout3js">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout3.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout4html">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout4.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout4js">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout4.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableDescriptionhtml">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableDescription.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableDescriptionjs">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableDescription.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableSamplehtml">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableSamplejs">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableTestshtml">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableTests.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplesFittableTestsjs">2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableTests.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplespackagejs">2013/sayaksarkar/trunk/lib/layout/fittable/samples/package.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesamplessamplecss">2013/sayaksarkar/trunk/lib/layout/fittable/samples/sample.css</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/fittable/source/</li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesourceFittableColumnsjs">2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableColumns.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesourceFittableLayoutcss">2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableLayout.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesourceFittableLayoutjs">2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableLayout.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesourceFittableRowsjs">2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableRows.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutfittablesourcepackagejs">2013/sayaksarkar/trunk/lib/layout/fittable/source/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/imageview/</li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewpackagejs">2013/sayaksarkar/trunk/lib/layout/imageview/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/imageview/samples/</li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesImageCarouselSamplecss">2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageCarouselSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesImageCarouselSamplehtml">2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageCarouselSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesImageCarouselSamplejs">2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageCarouselSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesImageViewSamplecss">2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageViewSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesImageViewSamplehtml">2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageViewSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesImageViewSamplejs">2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageViewSample.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/</li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesassetsearthjpg">2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/earth.jpg</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesassetsfaviconico">2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/favicon.ico</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesassetsglobejpg">2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/globe.jpg</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesassetsjupiterjpg">2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/jupiter.jpg</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesassetsmarsjpg">2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/mars.jpg</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesassetsmercuryjpg">2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/mercury.jpg</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesassetsneptunejpg">2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/neptune.jpg</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesassetspinpng">2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/pin.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesassetssaturnjpg">2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/saturn.jpg</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesassetsuranusjpg">2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/uranus.jpg</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplesassetsvenusjpg">2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/venus.jpg</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsamplespackagejs">2013/sayaksarkar/trunk/lib/layout/imageview/samples/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/imageview/source/</li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsourceImageCarouseljs">2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageCarousel.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsourceImageViewjs">2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageView.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsourceImageViewPincss">2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageViewPin.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsourceImageViewPinjs">2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageViewPin.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutimageviewsourcepackagejs">2013/sayaksarkar/trunk/lib/layout/imageview/source/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/list/</li>
<li><a href="#2013sayaksarkartrunkliblayoutlistpackagejs">2013/sayaksarkar/trunk/lib/layout/list/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/list/samples/</li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesFlyweightRepeaterSamplecss">2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesFlyweightRepeaterSamplehtml">2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesFlyweightRepeaterSamplejs">2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListAroundSamplecss">2013/sayaksarkar/trunk/lib/layout/list/samples/ListAroundSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListAroundSamplehtml">2013/sayaksarkar/trunk/lib/layout/list/samples/ListAroundSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListAroundSamplejs">2013/sayaksarkar/trunk/lib/layout/list/samples/ListAroundSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListBasicSamplecss">2013/sayaksarkar/trunk/lib/layout/list/samples/ListBasicSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListBasicSamplehtml">2013/sayaksarkar/trunk/lib/layout/list/samples/ListBasicSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListBasicSamplejs">2013/sayaksarkar/trunk/lib/layout/list/samples/ListBasicSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListContactsSamplecss">2013/sayaksarkar/trunk/lib/layout/list/samples/ListContactsSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListContactsSamplehtml">2013/sayaksarkar/trunk/lib/layout/list/samples/ListContactsSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListContactsSamplejs">2013/sayaksarkar/trunk/lib/layout/list/samples/ListContactsSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListLanguagesSamplecss">2013/sayaksarkar/trunk/lib/layout/list/samples/ListLanguagesSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListLanguagesSamplehtml">2013/sayaksarkar/trunk/lib/layout/list/samples/ListLanguagesSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListLanguagesSamplejs">2013/sayaksarkar/trunk/lib/layout/list/samples/ListLanguagesSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListNoSelectSamplehtml">2013/sayaksarkar/trunk/lib/layout/list/samples/ListNoSelectSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListNoSelectSamplejs">2013/sayaksarkar/trunk/lib/layout/list/samples/ListNoSelectSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListOnyxItemSamplehtml">2013/sayaksarkar/trunk/lib/layout/list/samples/ListOnyxItemSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListOnyxItemSamplejs">2013/sayaksarkar/trunk/lib/layout/list/samples/ListOnyxItemSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListPulldownSamplecss">2013/sayaksarkar/trunk/lib/layout/list/samples/ListPulldownSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListPulldownSamplehtml">2013/sayaksarkar/trunk/lib/layout/list/samples/ListPulldownSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesListPulldownSamplejs">2013/sayaksarkar/trunk/lib/layout/list/samples/ListPulldownSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesNameGeneratorjs">2013/sayaksarkar/trunk/lib/layout/list/samples/NameGenerator.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesPersistentSwipeableItemSamplecss">2013/sayaksarkar/trunk/lib/layout/list/samples/PersistentSwipeableItemSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesPersistentSwipeableItemSamplehtml">2013/sayaksarkar/trunk/lib/layout/list/samples/PersistentSwipeableItemSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesPersistentSwipeableItemSamplejs">2013/sayaksarkar/trunk/lib/layout/list/samples/PersistentSwipeableItemSample.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/list/samples/assets/</li>
<li>2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/</li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsangelpng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/angel.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsastrologerpng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/astrologer.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsathletepng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/athlete.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsbabypng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/baby.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsclownpng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/clown.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdevilpng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/devil.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdoctorpng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/doctor.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdudepng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdude2png">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude2.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdude3png">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude3.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdude4png">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude4.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdude5png">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude5.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdude6png">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude6.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsbgpng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/bg.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsitemhilitepng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/item-hilite.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetspulldownpng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/pulldown.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetspulluppng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/pullup.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsremoveiconpng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/remove-icon.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetssearchinputsearchpng">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/search-input-search.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplesassetsspinnergif">2013/sayaksarkar/trunk/lib/layout/list/samples/assets/spinner.gif</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsamplespackagejs">2013/sayaksarkar/trunk/lib/layout/list/samples/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/list/source/</li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsourceAlphaJumpListjs">2013/sayaksarkar/trunk/lib/layout/list/source/AlphaJumpList.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsourceAlphaJumpercss">2013/sayaksarkar/trunk/lib/layout/list/source/AlphaJumper.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsourceAlphaJumperjs">2013/sayaksarkar/trunk/lib/layout/list/source/AlphaJumper.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsourceAroundListjs">2013/sayaksarkar/trunk/lib/layout/list/source/AroundList.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsourceFlyweightRepeaterjs">2013/sayaksarkar/trunk/lib/layout/list/source/FlyweightRepeater.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsourceListcss">2013/sayaksarkar/trunk/lib/layout/list/source/List.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsourceListjs">2013/sayaksarkar/trunk/lib/layout/list/source/List.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsourcePulldownListcss">2013/sayaksarkar/trunk/lib/layout/list/source/PulldownList.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsourcePulldownListjs">2013/sayaksarkar/trunk/lib/layout/list/source/PulldownList.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsourcepackagejs">2013/sayaksarkar/trunk/lib/layout/list/source/package.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutlistsourcewippackagejs">2013/sayaksarkar/trunk/lib/layout/list/source/wip-package.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpackagejs">2013/sayaksarkar/trunk/lib/layout/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/panels/</li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelspackagejs">2013/sayaksarkar/trunk/lib/layout/panels/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/panels/samples/</li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesPanelsFlickrSamplecss">2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsFlickrSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesPanelsFlickrSamplehtml">2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsFlickrSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesPanelsFlickrSamplejs">2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsFlickrSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesPanelsSamplecss">2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesPanelsSamplehtml">2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesPanelsSamplejs">2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesPanelsSlidingSamplecss">2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSlidingSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesPanelsSlidingSamplehtml">2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSlidingSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesPanelsSlidingSamplejs">2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSlidingSample.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/</li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesassetssearchinputsearchpng">2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/search-input-search.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesassetsspinnerlargegif">2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/spinner-large.gif</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesassetsspinnergif">2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/spinner.gif</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplesmenutesthtml">2013/sayaksarkar/trunk/lib/layout/panels/samples/menutest.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssamplespackagejs">2013/sayaksarkar/trunk/lib/layout/panels/samples/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/panels/source/</li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssourcePanelscss">2013/sayaksarkar/trunk/lib/layout/panels/source/Panels.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssourcePanelsjs">2013/sayaksarkar/trunk/lib/layout/panels/source/Panels.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/</li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssourcearrangersArrangercss">2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/Arranger.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssourcearrangersArrangerjs">2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/Arranger.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssourcearrangersCardArrangerjs">2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CardArranger.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssourcearrangersCardSlideInArrangerjs">2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CardSlideInArranger.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssourcearrangersCarouselArrangerjs">2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CarouselArranger.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssourcearrangersCollapsingArrangerjs">2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CollapsingArranger.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssourcearrangersDockRightArrangerjs">2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/DockRightArranger.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssourcearrangersOtherArrangersjs">2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/OtherArrangers.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssourcearrangerspackagejs">2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/package.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutpanelssourcepackagejs">2013/sayaksarkar/trunk/lib/layout/panels/source/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/slideable/</li>
<li><a href="#2013sayaksarkartrunkliblayoutslideablepackagejs">2013/sayaksarkar/trunk/lib/layout/slideable/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/slideable/samples/</li>
<li><a href="#2013sayaksarkartrunkliblayoutslideablesamplesSlideableSamplecss">2013/sayaksarkar/trunk/lib/layout/slideable/samples/SlideableSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutslideablesamplesSlideableSamplehtml">2013/sayaksarkar/trunk/lib/layout/slideable/samples/SlideableSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutslideablesamplesSlideableSamplejs">2013/sayaksarkar/trunk/lib/layout/slideable/samples/SlideableSample.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutslideablesamplespackagejs">2013/sayaksarkar/trunk/lib/layout/slideable/samples/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/slideable/source/</li>
<li><a href="#2013sayaksarkartrunkliblayoutslideablesourceSlideablejs">2013/sayaksarkar/trunk/lib/layout/slideable/source/Slideable.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayoutslideablesourcepackagejs">2013/sayaksarkar/trunk/lib/layout/slideable/source/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/tree/</li>
<li><a href="#2013sayaksarkartrunkliblayouttreepackagejs">2013/sayaksarkar/trunk/lib/layout/tree/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/tree/samples/</li>
<li><a href="#2013sayaksarkartrunkliblayouttreesamplesTreeSamplecss">2013/sayaksarkar/trunk/lib/layout/tree/samples/TreeSample.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayouttreesamplesTreeSamplehtml">2013/sayaksarkar/trunk/lib/layout/tree/samples/TreeSample.html</a></li>
<li><a href="#2013sayaksarkartrunkliblayouttreesamplesTreeSamplejs">2013/sayaksarkar/trunk/lib/layout/tree/samples/TreeSample.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/</li>
<li><a href="#2013sayaksarkartrunkliblayouttreesamplesassetsfilepng">2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/file.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayouttreesamplesassetsfolderopenpng">2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/folder-open.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayouttreesamplesassetsfolderpng">2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/folder.png</a></li>
<li><a href="#2013sayaksarkartrunkliblayouttreesamplespackagejs">2013/sayaksarkar/trunk/lib/layout/tree/samples/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/layout/tree/source/</li>
<li><a href="#2013sayaksarkartrunkliblayouttreesourceNodecss">2013/sayaksarkar/trunk/lib/layout/tree/source/Node.css</a></li>
<li><a href="#2013sayaksarkartrunkliblayouttreesourceNodejs">2013/sayaksarkar/trunk/lib/layout/tree/source/Node.js</a></li>
<li><a href="#2013sayaksarkartrunkliblayouttreesourcepackagejs">2013/sayaksarkar/trunk/lib/layout/tree/source/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/onyx/</li>
<li><a href="#2013sayaksarkartrunklibonyxCONTRIBUTINGmd">2013/sayaksarkar/trunk/lib/onyx/CONTRIBUTING md</a></li>
<li><a href="#2013sayaksarkartrunklibonyxLICENSE20txt">2013/sayaksarkar/trunk/lib/onyx/LICENSE-2.0.txt</a></li>
<li><a href="#2013sayaksarkartrunklibonyxREADMEmd">2013/sayaksarkar/trunk/lib/onyx/README.md</a></li>
<li>2013/sayaksarkar/trunk/lib/onyx/css/</li>
<li><a href="#2013sayaksarkartrunklibonyxcssButtonless">2013/sayaksarkar/trunk/lib/onyx/css/Button.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssButtonColorsless">2013/sayaksarkar/trunk/lib/onyx/css/ButtonColors.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssCheckboxless">2013/sayaksarkar/trunk/lib/onyx/css/Checkbox.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssContextualPopupless">2013/sayaksarkar/trunk/lib/onyx/css/ContextualPopup.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssDatePickerless">2013/sayaksarkar/trunk/lib/onyx/css/DatePicker.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssGrabberless">2013/sayaksarkar/trunk/lib/onyx/css/Grabber.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssGroupboxless">2013/sayaksarkar/trunk/lib/onyx/css/Groupbox.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssIconless">2013/sayaksarkar/trunk/lib/onyx/css/Icon.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssInputless">2013/sayaksarkar/trunk/lib/onyx/css/Input.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssItemless">2013/sayaksarkar/trunk/lib/onyx/css/Item.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssMenuless">2013/sayaksarkar/trunk/lib/onyx/css/Menu.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssMoreToolbarless">2013/sayaksarkar/trunk/lib/onyx/css/MoreToolbar.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssPickerless">2013/sayaksarkar/trunk/lib/onyx/css/Picker.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssPopupless">2013/sayaksarkar/trunk/lib/onyx/css/Popup.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssProgressBarless">2013/sayaksarkar/trunk/lib/onyx/css/ProgressBar.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssProgressButtonless">2013/sayaksarkar/trunk/lib/onyx/css/ProgressButton.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssRadioButtonless">2013/sayaksarkar/trunk/lib/onyx/css/RadioButton.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssRangeSliderless">2013/sayaksarkar/trunk/lib/onyx/css/RangeSlider.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssRichTextless">2013/sayaksarkar/trunk/lib/onyx/css/RichText.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssScrimless">2013/sayaksarkar/trunk/lib/onyx/css/Scrim.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssSliderless">2013/sayaksarkar/trunk/lib/onyx/css/Slider.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssSpinnerless">2013/sayaksarkar/trunk/lib/onyx/css/Spinner.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssTabButtonless">2013/sayaksarkar/trunk/lib/onyx/css/TabButton.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssTextArealess">2013/sayaksarkar/trunk/lib/onyx/css/TextArea.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssTimePickerless">2013/sayaksarkar/trunk/lib/onyx/css/TimePicker.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssToggleButtonless">2013/sayaksarkar/trunk/lib/onyx/css/ToggleButton.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssToolbarless">2013/sayaksarkar/trunk/lib/onyx/css/Toolbar.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssTooltipless">2013/sayaksarkar/trunk/lib/onyx/css/Tooltip.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssonyxrulesless">2013/sayaksarkar/trunk/lib/onyx/css/onyx-rules.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssonyxvariablesless">2013/sayaksarkar/trunk/lib/onyx/css/onyx-variables.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssonyxcss">2013/sayaksarkar/trunk/lib/onyx/css/onyx.css</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcssonyxless">2013/sayaksarkar/trunk/lib/onyx/css/onyx.less</a></li>
<li><a href="#2013sayaksarkartrunklibonyxcsspackagejs">2013/sayaksarkar/trunk/lib/onyx/css/package.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxdeploybat">2013/sayaksarkar/trunk/lib/onyx/deploy.bat</a></li>
<li><a href="#2013sayaksarkartrunklibonyxdeploysh">2013/sayaksarkar/trunk/lib/onyx/deploy.sh</a></li>
<li>2013/sayaksarkar/trunk/lib/onyx/design/</li>
<li><a href="#2013sayaksarkartrunklibonyxdesigninlinecontrolledhtml">2013/sayaksarkar/trunk/lib/onyx/design/inline-controlled.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxdesigninlinehtml">2013/sayaksarkar/trunk/lib/onyx/design/inline.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxdesignmenuiconbookmarkpng">2013/sayaksarkar/trunk/lib/onyx/design/menu-icon-bookmark.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyxdesigntoolbarextendedhtml">2013/sayaksarkar/trunk/lib/onyx/design/toolbar-extended.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxdesigntoolbarhtml">2013/sayaksarkar/trunk/lib/onyx/design/toolbar.html</a></li>
<li>2013/sayaksarkar/trunk/lib/onyx/images/</li>
<li><a href="#2013sayaksarkartrunklibonyximagescheckboxpng">2013/sayaksarkar/trunk/lib/onyx/images/checkbox.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyximagesgrabbuttonpng">2013/sayaksarkar/trunk/lib/onyx/images/grabbutton.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyximagesgradientinvertpng">2013/sayaksarkar/trunk/lib/onyx/images/gradient-invert.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyximagesgradientpng">2013/sayaksarkar/trunk/lib/onyx/images/gradient.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyximagesmorepng">2013/sayaksarkar/trunk/lib/onyx/images/more.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyximagesprogressbuttoncancelpng">2013/sayaksarkar/trunk/lib/onyx/images/progress-button-cancel.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyximagessearchinputcancelpng">2013/sayaksarkar/trunk/lib/onyx/images/search-input-cancel.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyximagessearchinputsearchpng">2013/sayaksarkar/trunk/lib/onyx/images/search-input-search.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyximagessliderhandlepng">2013/sayaksarkar/trunk/lib/onyx/images/slider-handle.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyximagesspinnerdarkgif">2013/sayaksarkar/trunk/lib/onyx/images/spinner-dark.gif</a></li>
<li><a href="#2013sayaksarkartrunklibonyximagesspinnerlightgif">2013/sayaksarkar/trunk/lib/onyx/images/spinner-light.gif</a></li>
<li><a href="#2013sayaksarkartrunklibonyxpackagejs">2013/sayaksarkar/trunk/lib/onyx/package.js</a></li>
<li>2013/sayaksarkar/trunk/lib/onyx/samples/</li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesButtonGroupSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/ButtonGroupSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesButtonGroupSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/ButtonGroupSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesButtonSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/ButtonSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesButtonSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/ButtonSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesCheckboxSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/CheckboxSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesCheckboxSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/CheckboxSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesContextualPopupSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/ContextualPopupSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesContextualPopupSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/ContextualPopupSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesDatePickerSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/DatePickerSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesDatePickerSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/DatePickerSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesDrawerSamplecss">2013/sayaksarkar/trunk/lib/onyx/samples/DrawerSample.css</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesDrawerSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/DrawerSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesDrawerSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/DrawerSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesGroupboxSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/GroupboxSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesGroupboxSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/GroupboxSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesIconButtonSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/IconButtonSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesIconButtonSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/IconButtonSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesInputSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/InputSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesInputSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/InputSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesMenuSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/MenuSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesMenuSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/MenuSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesMoreToolbarSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/MoreToolbarSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesMoreToolbarSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/MoreToolbarSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesPickerSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/PickerSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesPickerSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/PickerSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesPopupSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/PopupSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesPopupSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/PopupSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesProgressSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/ProgressSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesProgressSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/ProgressSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesSliderSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/SliderSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesSliderSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/SliderSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesSpinnerSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/SpinnerSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesSpinnerSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/SpinnerSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesTimePickerSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/TimePickerSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesTimePickerSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/TimePickerSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesToggleButtonSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/ToggleButtonSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesToggleButtonSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/ToggleButtonSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesToolbarSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/ToolbarSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesToolbarSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/ToolbarSample.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesTooltipSamplehtml">2013/sayaksarkar/trunk/lib/onyx/samples/TooltipSample.html</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesTooltipSamplejs">2013/sayaksarkar/trunk/lib/onyx/samples/TooltipSample.js</a></li>
<li>2013/sayaksarkar/trunk/lib/onyx/samples/assets/</li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesassetsfaviconico">2013/sayaksarkar/trunk/lib/onyx/samples/assets/favicon.ico</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesassetsfish_bowlpng">2013/sayaksarkar/trunk/lib/onyx/samples/assets/fish_bowl.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesassetsmenuiconbookmarkpng">2013/sayaksarkar/trunk/lib/onyx/samples/assets/menu-icon-bookmark.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplesassetssearchinputsearchpng">2013/sayaksarkar/trunk/lib/onyx/samples/assets/search-input-search.png</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplespackagejs">2013/sayaksarkar/trunk/lib/onyx/samples/package.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsamplessamplecss">2013/sayaksarkar/trunk/lib/onyx/samples/sample.css</a></li>
<li>2013/sayaksarkar/trunk/lib/onyx/source/</li>
<li><a href="#2013sayaksarkartrunklibonyxsourceButtonjs">2013/sayaksarkar/trunk/lib/onyx/source/Button.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceCheckboxjs">2013/sayaksarkar/trunk/lib/onyx/source/Checkbox.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceContextualPopupjs">2013/sayaksarkar/trunk/lib/onyx/source/ContextualPopup.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceDatePickerjs">2013/sayaksarkar/trunk/lib/onyx/source/DatePicker.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceDrawerjs">2013/sayaksarkar/trunk/lib/onyx/source/Drawer.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceFlyweightPickerjs">2013/sayaksarkar/trunk/lib/onyx/source/FlyweightPicker.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceGrabberjs">2013/sayaksarkar/trunk/lib/onyx/source/Grabber.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceGroupboxjs">2013/sayaksarkar/trunk/lib/onyx/source/Groupbox.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceIconjs">2013/sayaksarkar/trunk/lib/onyx/source/Icon.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceIconButtonjs">2013/sayaksarkar/trunk/lib/onyx/source/IconButton.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceInputjs">2013/sayaksarkar/trunk/lib/onyx/source/Input.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceInputDecoratorjs">2013/sayaksarkar/trunk/lib/onyx/source/InputDecorator.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceIntegerPickerjs">2013/sayaksarkar/trunk/lib/onyx/source/IntegerPicker.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceItemjs">2013/sayaksarkar/trunk/lib/onyx/source/Item.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceMenujs">2013/sayaksarkar/trunk/lib/onyx/source/Menu.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceMenuDecoratorjs">2013/sayaksarkar/trunk/lib/onyx/source/MenuDecorator.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceMenuItemjs">2013/sayaksarkar/trunk/lib/onyx/source/MenuItem.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceMoreToolbarjs">2013/sayaksarkar/trunk/lib/onyx/source/MoreToolbar.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourcePickerjs">2013/sayaksarkar/trunk/lib/onyx/source/Picker.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourcePickerButtonjs">2013/sayaksarkar/trunk/lib/onyx/source/PickerButton.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourcePickerDecoratorjs">2013/sayaksarkar/trunk/lib/onyx/source/PickerDecorator.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourcePopupjs">2013/sayaksarkar/trunk/lib/onyx/source/Popup.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceProgressBarjs">2013/sayaksarkar/trunk/lib/onyx/source/ProgressBar.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceProgressButtonjs">2013/sayaksarkar/trunk/lib/onyx/source/ProgressButton.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceRadioButtonjs">2013/sayaksarkar/trunk/lib/onyx/source/RadioButton.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceRadioGroupjs">2013/sayaksarkar/trunk/lib/onyx/source/RadioGroup.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceRangeSliderjs">2013/sayaksarkar/trunk/lib/onyx/source/RangeSlider.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceRichTextjs">2013/sayaksarkar/trunk/lib/onyx/source/RichText.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceScrimjs">2013/sayaksarkar/trunk/lib/onyx/source/Scrim.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceSliderjs">2013/sayaksarkar/trunk/lib/onyx/source/Slider.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceSpinnerjs">2013/sayaksarkar/trunk/lib/onyx/source/Spinner.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceTabPanelsjs">2013/sayaksarkar/trunk/lib/onyx/source/TabPanels.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceTextAreajs">2013/sayaksarkar/trunk/lib/onyx/source/TextArea.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceTimePickerjs">2013/sayaksarkar/trunk/lib/onyx/source/TimePicker.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceToggleButtonjs">2013/sayaksarkar/trunk/lib/onyx/source/ToggleButton.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceToggleIconButtonjs">2013/sayaksarkar/trunk/lib/onyx/source/ToggleIconButton.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceToolbarjs">2013/sayaksarkar/trunk/lib/onyx/source/Toolbar.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceTooltipjs">2013/sayaksarkar/trunk/lib/onyx/source/Tooltip.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourceTooltipDecoratorjs">2013/sayaksarkar/trunk/lib/onyx/source/TooltipDecorator.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourcedesignjs">2013/sayaksarkar/trunk/lib/onyx/source/design.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourcepackagejs">2013/sayaksarkar/trunk/lib/onyx/source/package.js</a></li>
<li><a href="#2013sayaksarkartrunklibonyxsourcewippackagejs">2013/sayaksarkar/trunk/lib/onyx/source/wip-package.js</a></li>
<li><a href="#2013sayaksarkartrunkmanifestwebapp">2013/sayaksarkar/trunk/manifest.webapp</a></li>
<li><a href="#2013sayaksarkartrunkpackagejs">2013/sayaksarkar/trunk/package.js</a></li>
<li>2013/sayaksarkar/trunk/source/</li>
<li><a href="#2013sayaksarkartrunksourceappcss">2013/sayaksarkar/trunk/source/app.css</a></li>
<li><a href="#2013sayaksarkartrunksourcecomposejs">2013/sayaksarkar/trunk/source/compose.js</a></li>
<li><a href="#2013sayaksarkartrunksourcepackagejs">2013/sayaksarkar/trunk/source/package.js</a></li>
<li><a href="#2013sayaksarkartrunksourcepostsjs">2013/sayaksarkar/trunk/source/posts.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="2013sayaksarkartrunkREADMEmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/README.md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/README.md (rev 0)
+++ 2013/sayaksarkar/trunk/README.md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+WordPress for Firefox OS
+========================
+
+WordPress Web App for the Firefox OS mobile platform.
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyoCONTRIBUTINGmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/CONTRIBUTING md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/CONTRIBUTING md (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/CONTRIBUTING md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+# Contributions
+
+Contributions are welcome for Enyo and its associated libraries including onyx and layout.
+
+Please see [Contributing to Enyo](http://enyojs.com/community/contribute/) for details
+on our contribution policy and guidelines for use of the Enyo-DCO-1.1-Signed-off-by
+line in your commits and pull requests.
+
+If you're interested in introducing new kinds, you might also consider hosting your own repo
+and contributing to the [Enyo community gallery](http://enyojs.com/gallery).
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyoLICENSE20txt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/LICENSE-2.0.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/LICENSE-2.0.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/LICENSE-2.0.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,202 @@
</span><ins>+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyoREADMEmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/README.md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/README.md (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/README.md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,146 @@
</span><ins>+### Looking for the issue tracker?
+It's moved to [https://enyojs.atlassian.net](https://enyojs.atlassian.net).
+
+---
+
+# Quick Info
+
+## Core
+
+This repository contains Enyo core. We've pared it down to the essentials, so folks can work at the metal. Widget libraries, g11n code, and other fancy bits are optional packages.
+
+## Lib
+
+Packages should go in a folder named _lib_ (e.g. the _extra_ or _canvas_ repositories on GitHub). _lib_ is a magic name that enyo uses to work with add-on packages. It's recommended you create a _lib_ folder as sibling to _enyo_ and keep your packages there, but you can make as many _lib_ folders as you like and put them anywhere.
+
+## Warning about file://
+
+_Note_: in Chrome, various samples will not work from file:// because of Chrome's security policy. Run from a local http server, use the --allow-file-access-from-files in Chrome, or use the online versions at http://enyojs.com.
+
+# What Is Enyo
+
+Enyo is an object-oriented JavaScript application framework emphasizing modularity and encapsulation. Enyo is suitable for small and large-scale applications.
+
+Enyo up to 1.x was the underlying framework used to develop applications for HP's TouchPad tablet. Enyo as shipped on the TouchPad included an complete set of user interface components and service wrappers. What you will find here is Enyo 2, what we informally call _core_: the primary infrastructure needed to support any number of Enyo-based libraries. Not to worry, Enyo 1.x itself is open-source licensed, and work is progressing on packaging up those controls and goodies to work with Enyo 2.
+
+Enyo was designed from the beginning to be highly extensible. This repository reflects a small working set of code, that can be expanded with any number of libraries or plugins.
+
+Enyo 2 is lightweight, easy to digest, and powerful.
+
+# What Do I Get
+
+The core code includes the Enyo kernel, the DOM extensions, some Ajax (XHR) tools, and basic wrapper kinds for a lot of DOM form elements. These things are actually separable (it's easy to make micro-builds of Enyo), but we believe this is a useful working set.
+
+The Enyo 2 kernel provides a modularity concept (Component) and a view concept (UiComponent). The DOM aspect includes a widget concept (Control) and an extensible event system (Dispatcher). The Ajax package includes basic xhr functionality and an implementation of xhr as a Component (Ajax). The touch package provides platform-optimized scrollers, while the UI package provides base kinds for common controls like buttons and popups.
+
+Just these pieces are sufficient to create large applications using the Enyo encapsulation model. Developers that want only this low-level code are encouraged to roll-their-own. For those that want a richer set of tools, there are some pre-built libraries already available, and much more on the way.
+
+# Why Do I Care
+
+First is our emphasis on cross-platform: Enyo core works on both desktop and mobile browsers.
+
+Second is Enyo's building block approach to applications. Each piece of an application is a Component, and Components are constructed out of other Components.
+
+For example, it's easy to define a combination of an `<input>` tag with a `<label>` tag into one _LabeledInput_ Component.
+
+Now I can use (and re-use) LabeledInput as one atomic piece.
+
+But that's just the beginning. Ultimately, large pieces of functionality can be exposed as single Components, for example a fancy report generator, or a color picker, or an entire painting application.
+
+Use the Enyo encapsulation model to divide and conquer large projects. No particular piece of an application need be especially complex. Because combining pieces is central, it's natural to factor complex sections into smaller pieces. And because of the modularity, all these pieces tend to be reusable, in the same project, in other projects, or even for the public at large.
+
+This is all part of our strategy to allow developers to focus on creativity and avoid Repeating Themselves.
+
+# That's a Lot of Talk
+
+The core Enyo design was proven out by the complex applications HP developed for the TouchPad platform. We don't claim this was particularly easy, there were a lot of hardworking developers on the apps teams, but we are confident the Enyo principles are effective on a large scale.
+
+In any case, roll your sleeves up and try it for yourself.
+
+# Give me the Basics
+
+Here is an Enyo Hello World:
+
+```html
+<!doctype html>
+<html>
+<head>
+ <title>Enyo</title>
+ <script src="enyojs/2.2.0/enyo.js" type="text/javascript"></script>
+ <link href="enyojs/2.2.0/enyo.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+ <script type="text/javascript">
+ new enyo.Control({content: "Hello From Enyo"}).renderInto(document.body);
+ </script>
+</body>
+</html>
+```
+
+This example loads an enyo.js build from _enyojs/2.2.0/_. If you downloaded the SDK you have a versioned build file. If you pulled from GitHub, you can either make your own build using a minify script in _enyo/source/minify_ (requires Node), or you can load directly from the source (_enyo/source/enyo.js_). Loading from source is also called 'debug loading' because the modules are loaded as individual files, which is easier for debugging, but much less efficient.
+
+The base enyo.Control works much like an HTML tag. You can assign _classes_ and _attributes_ and give it a _style_. E.g.
+
+```javascript
+new enyo.Control({content: "Hello From Enyo", classes: "foo", style: "color: red",
+ attributes: {tabIndex: 0}}).renderInto(document.body);
+```
+
+produces
+
+```html
+<div class="foo" style="color: red;" tabIndex="0">Hello From Enyo</div>
+```
+
+Now, the good parts start when you combine more than one Control, e.g.
+
+```javascript
+new enyo.Control({
+ components: [
+ {content: "Hello From Enyo"},
+ {tag: "hr"}
+ ]
+}).renderInto(document.body);
+```
+
+This Control now encapsulates two Controls into one scope (we can encapsulate any type of Component, that's why the property is called _components_. Controls are one kind of Component.) The outer Control is responsible for the encapsulated components: it manages their lifecycle, listens to their messages, and maintains references to them. For example:
+
+```javascript
+new enyo.Control({
+ components: [
+ {name: "hello", content: "Hello From Enyo", ontap: "helloTap"},
+ {tag: "hr"}
+ ],
+ helloTap: function() {
+ this.$.hello.addStyles("color: red");
+ }
+}).renderInto(document.body);
+```
+
+Here we've given one of the components a name ('hello') and told it to send a 'helloTap' message when it's tapped (tap is basically the same as the DOM click event, but it works in both mouse and touch environments). The '$' property is a hash that references all the sub-components (we don't store these references directly on _this_ to avoid name conflicts). Notice there is no add/remove machinery to listen to this event, that's all taken care of.
+
+The main point is that 'hello' and the 'hr', their references and behavior, are completely contained inside the outer control. Now, to re-use this, we need to make it a prototype.
+
+Enyo contains a constructor/prototype-generator that we call enyo.kind. Constructors that enyo.kind produces are called _kinds_. Kinds are not magic, they are just regular old JavaScript constructors. Using the enyo.kind factory however allows us to remove boilerplate from our prototype generation (DRY) and have compact syntax. We can convert the Control above to a kind like so:
+
+```javascript
+enyo.kind({
+ name: "Hello",
+ kind: enyo.Control,
+ components: [
+ {name: "hello", content: "Hello From Enyo", ontap: "helloTap"},
+ {tag: "hr"}
+ ],
+ helloTap: function() {
+ this.$.hello.addStyles("color: red");
+ }
+});
+// make two, they're small
+new enyo.Control({
+ component: [ {kind: "Hello"}, {kind: "Hello"} ]
+ }).renderInto(document.body);
+```
+
+The code above creates a new kind called "Hello" derived from enyo.Control. It contains some components and some behavior. I can create as many "Hello" objects as I want, each instance is independent, and the user of a "Hello" doesn't need to know anything about its internals.
+
+This ability to define encapsulated objects and behavior (Components) and to re-use those encapsulations as prototypes (kinds) is money.
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyoenyojs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/enyo.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/enyo.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/enyo.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+(function() {
+ // enyo can use information from the script tag that loads this bootstrap file
+ var thisScript = "enyo.js";
+
+ enyo = window.enyo || {};
+
+ enyo.locateScript = function(inName) {
+ var scripts = document.getElementsByTagName("script");
+ for (var i=scripts.length-1, s, src, l=inName.length; (i>=0) && (s=scripts[i]); i--) {
+ if (!s.located) {
+ src = s.getAttribute("src") || "";
+ if (src.slice(-l) == inName) {
+ s.located = true;
+ return {path: src.slice(0, Math.max(0, src.lastIndexOf("/"))), node: s};
+ }
+ }
+ }
+ };
+
+ enyo.args = enyo.args || {};
+
+ var tag = enyo.locateScript(thisScript);
+ if (tag) {
+ // infer the framework path from the document, unless the user has specified one explicitly
+ enyo.args.root = (enyo.args.root || tag.path);
+ // all attributes of the bootstrap script tag become enyo.args
+ for (var i=0, al = tag.node.attributes.length, it; (i < al) && (it = tag.node.attributes.item(i)); i++) {
+ enyo.args[it.nodeName] = it.value;
+ }
+ }
+
+ var root = enyo.args.root;
+
+ var script = function(inSrc) {
+ document.write('<scri' + 'pt src="' + root + "/source/boot/" + inSrc + '"></scri' + 'pt>');
+ };
+
+ script("../../loader.js");
+ script("boot.js");
+ script("../package.js");
+})();
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyoloaderjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/loader.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/loader.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/loader.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,302 @@
</span><ins>+(function() {
+ enyo = window.enyo || {};
+
+ enyo.pathResolverFactory = function() {
+ this.paths = {};
+ };
+
+ enyo.pathResolverFactory.prototype = {
+ addPath: function(inName, inPath) {
+ return this.paths[inName] = inPath;
+ },
+ addPaths: function(inPaths) {
+ if (inPaths) {
+ for (var n in inPaths) {
+ this.addPath(n, inPaths[n]);
+ }
+ }
+ },
+ includeTrailingSlash: function(inPath) {
+ return (inPath && inPath.slice(-1) !== "/") ? inPath + "/" : inPath;
+ },
+ // match $name
+ rewritePattern: /\$([^\/\\]*)(\/)?/g,
+ // replace macros of the form $pathname with the mapped value of paths.pathname
+ rewrite: function (inPath) {
+ var working, its = this.includeTrailingSlash, paths = this.paths;
+ var fn = function(macro, name) {
+ working = true;
+ return its(paths[name]) || '';
+ };
+ var result = inPath;
+ do {
+ working = false;
+ result = result.replace(this.rewritePattern, fn);
+ } while (working);
+ return result;
+ }
+ };
+
+ enyo.path = new enyo.pathResolverFactory();
+
+ enyo.loaderFactory = function(inMachine, inPathResolver) {
+ this.machine = inMachine;
+ // package information
+ this.packages = [];
+ // module information
+ this.modules = [];
+ // stylesheet paths
+ this.sheets = [];
+ // (protected) internal dependency stack
+ this.stack = [];
+ this.pathResolver = inPathResolver || enyo.path;
+ this.packageName = "";
+ this.packageFolder = "";
+ this.finishCallbacks = {};
+ };
+
+ enyo.loaderFactory.prototype = {
+ verbose: false,
+ loadScript: function(inScript) {
+ this.machine.script(inScript);
+ },
+ loadSheet: function(inSheet) {
+ this.machine.sheet(inSheet);
+ },
+ loadPackage: function(inPackage) {
+ this.machine.script(inPackage);
+ },
+ report: function() {
+ },
+ //
+ load: function(/*<inDependency0, inDependency1 ...>*/) {
+ // begin processing dependencies
+ this.more({
+ index: 0,
+ depends: arguments || []
+ });
+ },
+ more: function(inBlock) {
+ // a 'block' is a dependency list with a bookmark
+ // the bookmark (index) allows us to interrupt
+ // processing and then continue asynchronously.
+ if (inBlock) {
+ // returns true if this block has asynchronous requirements
+ // in that case, we unwind the stack. The asynchronous loader
+ // must provide the continuation (by calling 'more' again).
+ if (this.continueBlock(inBlock)) {
+ return;
+ }
+ }
+ // A package is now complete. Pop the block that was interrupted for that package (if any).
+ var block = this.stack.pop();
+ if (block) {
+ // block.packageName is the name of the package that interrupted us
+ //this.report("finished package", block.packageName);
+ if (this.verbose) {
+ console.groupEnd("* finish package (" + (block.packageName || "anon") + ")");
+ }
+ // cache the folder for the currently processing package
+ this.packageFolder = block.folder;
+ // no current package
+ this.packageName = "";
+ // process this new block
+ this.more(block);
+ } else {
+ this.finish();
+ }
+ },
+ finish: function() {
+ this.packageFolder = "";
+ if (this.verbose) {
+ console.log("-------------- fini");
+ }
+ for (var i in this.finishCallbacks) {
+ if (this.finishCallbacks[i]) {
+ this.finishCallbacks[i]();
+ this.finishCallbacks[i] = null;
+ }
+ }
+ },
+ continueBlock: function(inBlock) {
+ while (inBlock.index < inBlock.depends.length) {
+ var d = inBlock.depends[inBlock.index++];
+ if (d) {
+ if (typeof d == "string") {
+ if (this.require(d, inBlock)) {
+ // return true to indicate we need to interrupt
+ // processing until asynchronous file load completes
+ // the load process itself must provide the
+ // continuation
+ return true;
+ }
+ } else {
+ this.pathResolver.addPaths(d);
+ }
+ }
+ }
+ },
+ require: function(inPath, inBlock) {
+ // process aliases
+ var path = this.pathResolver.rewrite(inPath);
+ // get path root
+ var prefix = this.getPathPrefix(inPath);
+ // assemble path
+ path = prefix + path;
+ // process path
+ if ((path.slice(-4) == ".css") || (path.slice(-5) == ".less")) {
+ if (this.verbose) {
+ console.log("+ stylesheet: [" + prefix + "][" + inPath + "]");
+ }
+ this.requireStylesheet(path);
+ } else if (path.slice(-3) == ".js" && path.slice(-10) != "package.js") {
+ if (this.verbose) {
+ console.log("+ module: [" + prefix + "][" + inPath + "]");
+ }
+ this.requireScript(inPath, path);
+ } else {
+ // package
+ this.requirePackage(path, inBlock);
+ // return true to indicate a package was located and
+ // we need to interrupt further processing until it's completed
+ return true;
+ }
+ },
+ getPathPrefix: function(inPath) {
+ var delim = inPath.slice(0, 1);
+ if ((delim != "/") && (delim != "\\") && (delim != "$") && !/^https?:/i.test(inPath)) {
+ return this.packageFolder;
+ }
+ return "";
+ },
+ requireStylesheet: function(inPath) {
+ // stylesheet
+ this.sheets.push(inPath);
+ this.loadSheet(inPath);
+ },
+ requireScript: function(inRawPath, inPath) {
+ // script file
+ this.modules.push({
+ packageName: this.packageName,
+ rawPath: inRawPath,
+ path: inPath
+ });
+ this.loadScript(inPath);
+ },
+ decodePackagePath: function(inPath) {
+ // A package path can be encoded in two ways:
+ //
+ // 1. [folder]
+ // 2. [folder]/[*package.js]
+ //
+ // Note: manifest file name must end in "package.js"
+ //
+ var alias = '', target = '', folder = '', manifest = 'package.js';
+ // convert back slashes to forward slashes, remove double slashes, split on slash
+ var parts = inPath.replace(/\\/g, "/").replace(/\/\//g, "/").replace(/:\//, "://").split("/");
+ var i, p;
+ if (parts.length) {
+ // if inPath has a trailing slash, parts has an empty string which we pop off and ignore
+ var name = parts.pop() || parts.pop() || "";
+ // test if name includes the manifest tag
+ if (name.slice(-manifest.length) !== manifest) {
+ // if not a manifest name, it's part of the folder path
+ parts.push(name);
+ } else {
+ // otherwise this is the manifest name
+ manifest = name;
+ }
+ //
+ folder = parts.join("/");
+ folder = (folder ? folder + "/" : "");
+ manifest = folder + manifest;
+ //
+ // build friendly aliasing:
+ //
+ for (i=parts.length-1; i >= 0; i--) {
+ if (parts[i] == "source") {
+ parts.splice(i, 1);
+ break;
+ }
+ }
+ target = parts.join("/");
+ //
+ // portable aliasing:
+ //
+ // packages that are rooted at a folder named "enyo" or "lib" do not
+ // include that root path in their alias
+ //
+ // remove */lib or */enyo prefix
+ //
+ // e.g. foo/bar/baz/lib/zot -> zot package
+ //
+ for (i=parts.length-1; (p=parts[i]); i--) {
+ if (p == "lib" || p == "enyo") {
+ parts = parts.slice(i+1);
+ break;
+ }
+ }
+ // remove ".." and "."
+ for (i=parts.length-1; (p=parts[i]); i--) {
+ if (p == ".." || p == ".") {
+ parts.splice(i, 1);
+ }
+ }
+ //
+ alias = parts.join("-");
+ }
+ return {
+ alias: alias,
+ target: target,
+ folder: folder,
+ manifest: manifest
+ };
+ },
+ aliasPackage: function(inPath) {
+ var parts = this.decodePackagePath(inPath);
+ // cache manifest path
+ this.manifest = parts.manifest;
+ // cache package info for named packages
+ if (parts.alias) {
+ // debug only
+ /*
+ var old = this.pathResolver.paths[parts.name];
+ if (old && old != parts.folder) {
+ this.verbose && console.warn("mapping alias [" + parts.name + "] to [" + parts.folder + "] replacing [" + old + "]");
+ }
+ this.verbose && console.log("mapping alias [" + parts.name + "] to [" + parts.folder + "]");
+ */
+ //
+ // create a path alias for this package
+ this.pathResolver.addPath(parts.alias, parts.target);
+ //
+ // cache current name
+ this.packageName = parts.alias;
+ // cache package information
+ this.packages.push({
+ name: parts.alias,
+ folder: parts.folder
+ });
+ }
+ // cache current folder
+ this.packageFolder = parts.folder;
+ },
+ requirePackage: function(inPath, inBlock) {
+ // cache the interrupted packageFolder
+ inBlock.folder = this.packageFolder;
+ this.aliasPackage(inPath);
+ // cache the name of the package 'inBlock' is loading now
+ inBlock.packageName = this.packageName;
+ // push inBlock on the continuation stack
+ this.stack.push(inBlock);
+ // console/user reporting
+ this.report("loading package", this.packageName);
+ if (this.verbose) {
+ console.group("* start package [" + this.packageName + "]");
+ }
+ // load the actual package. the package MUST call a continuation function
+ // or the process will halt.
+ this.loadPackage(this.manifest);
+ }
+ };
+})();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyominifyminifybat"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/minify/minify.bat (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/minify/minify.bat (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/minify/minify.bat 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+@ECHO OFF
+REM FIXME: minify has a problem if 'package.js' is not in CWD, hence push, cd, pop
+PUSHD "%CD%"
+CD "%~dp0"
+CALL ..\tools\minify.bat package.js -no-alias -output ..\..\build\enyo %*
+POPD
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyominifyminifysh"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/minify/minify.sh (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/minify/minify.sh (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/minify/minify.sh 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+#!/bin/sh
+cd $(dirname $0)
+../tools/minify.sh package.js -no-alias -output ../../build/enyo
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/minify/minify.sh
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyominifypackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/minify/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/minify/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/minify/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+enyo.depends(
+ "../source/boot",
+ "../source"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyopackagejson"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/package.json (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/package.json (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/package.json 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+{
+ "name": "enyo",
+ "filename": "enyo.js",
+ "version": "2.2.0",
+ "description":"Enyo is an open source object-oriented JavaScript framework emphasizing encapsulation and modularity. Enyo contains everything you need to create a fast, scalable mobile or web application.",
+ "homepage": "http://enyojs.com/",
+ "keywords": [ "framework", "toolkit", "components", "mobile", "webOS" ],
+ "maintainers": [{
+ "name": "Enyo JS Framework Team (HP)",
+ "web": "http://enyojs.com/"
+ }],
+ "licenses": [{
+ "type": "Apache-2.0", "url": "http://www.apache.org/licenses/LICENSE-2.0"
+ }],
+ "bugs": "https://jira.enyojs.com/",
+ "repositories": [{
+ "type": "git", "url": "http://github.com/enyojs/enyo"
+ }]
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesAjaxSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/AjaxSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/AjaxSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/AjaxSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+.ajax-sample {
+ padding: 15px;
+}
+
+.ajax-sample-source {
+ padding:15px;
+ font-family: monospace;
+ font-size: 12px;
+ white-space: pre-wrap;
+ box-sizing: border-box;
+ width:100%;
+ height:100%;
+ margin-top:15px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesAjaxSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/AjaxSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/AjaxSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/AjaxSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <title>AJAX Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../lib/layout/package.js" type="text/javascript"></script>
+ <script src="../../lib/onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="AjaxSample.css" rel="stylesheet">
+ <script src="AjaxSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body class="onyx">
+<script type="text/javascript">
+ new enyo.sample.AjaxSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesAjaxSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/AjaxSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/AjaxSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/AjaxSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.AjaxSample",
+ kind: "FittableRows",
+ classes: "enyo-fit ajax-sample",
+ components: [
+ {kind: "FittableColumns", classes:"onyx-toolbar-inline", components: [
+ {content: "YQL: "},
+ {kind: "onyx.Input", name:"query", fit:true, value:'select * from upcoming.events where woeid in (select woeid from geo.places where text="Sunnyvale, CA")'},
+ {kind: "onyx.Button", content:"Fetch", ontap:"fetch"}
+ ]},
+ {kind: "FittableColumns", classes:"onyx-toolbar-inline", components: [
+ {content: "URL: "},
+ {kind: "onyx.Input", name:"baseUrl", fit:true, value:'http://query.yahooapis.com/v1/public/yql?format=json'}
+ ]},
+ {kind: "onyx.TextArea", fit:true, classes:"ajax-sample-source"}
+ ],
+ fetch: function() {
+ var ajax = new enyo.Ajax({
+ url: this.$.baseUrl.getValue()
+ });
+ // send parameters the remote service using the 'go()' method
+ ajax.go({
+ q: this.$.query.getValue()
+ });
+ // attach responders to the transaction object
+ ajax.response(this, "processResponse");
+ // handle error
+ ajax.error(this, "processError");
+ },
+ processResponse: function(inSender, inResponse) {
+ // do something with it
+ this.$.textArea.setValue(JSON.stringify(inResponse, null, 2));
+ },
+ processError: function(inSender, inResponse) {
+ alert("Error!");
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesGestureSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/GestureSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/GestureSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/GestureSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+.gesture-sample {
+ padding: 15px;
+}
+
+.gesture-sample > * {
+ margin-bottom:10px;
+}
+
+.gesture-sample-pad {
+ border-radius: 5px;
+ background-color: #888;
+ color: #686868;
+ text-shadow:#AAA 0px 1px 0, #000 0 -1px 0;
+ text-align:center;
+ padding-top:15%;
+ font-size:30px;
+ overflow:hidden;
+}
+
+.gesture-sample-note {
+ font-size:15px;
+ text-shadow:none;
+}
+
+.gesture-sample-padded > * {
+ padding:5px;
+}
+
+.gesture-sample-left > * {
+ text-align:left;
+}
+
+.gesture-sample-setting {
+ font-size: 15px;
+ padding: 10px;
+ min-height: 30px;
+ line-height: 30px;
+}
+.gesture-sample-setting > * {
+ display: inline-block;
+}
+
+.gesture-sample-setting > :last-child {
+ float: right;
+}
+
+@media all and (max-height:600px) {
+ .gesture-sample-truncate {
+ width:100%;
+ word-wrap:normal;
+ white-space:nowrap;
+ overflow:hidden;
+ -o-text-overflow:ellipsis;
+ text-overflow:ellipsis;
+ }
+}
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesGestureSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/GestureSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/GestureSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/GestureSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <title>Gesture Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../lib/layout/package.js" type="text/javascript"></script>
+ <script src="../../lib/onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="GestureSample.css" rel="stylesheet">
+ <script src="GestureSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body class="onyx">
+<script type="text/javascript">
+ new enyo.sample.GestureSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesGestureSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/GestureSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/GestureSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/GestureSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,198 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.GestureSample",
+ kind: "FittableRows",
+ classes: "gesture-sample enyo-fit enyo-unselectable",
+ components: [
+ {
+ classes:"gesture-sample-pad",
+ fit:true,
+ ondown: "handleEvent",
+ onup: "handleEvent",
+ ontap: "handleEvent",
+ onmove: "handleEvent",
+ onenter: "handleEvent",
+ onleave: "handleEvent",
+ ondragstart: "handleEvent",
+ ondrag: "handleEvent",
+ ondragover: "handleEvent",
+ onhold: "handleEvent",
+ onrelease: "handleEvent",
+ onholdpulse: "handleEvent",
+ onflick: "handleEvent",
+ ongesturestart: "handleEvent",
+ ongesturechange: "handleEvent",
+ ongestureend: "handleEvent",
+ components: [
+ {content: "Perform gestures here"},
+ {classes: "gesture-sample-note", content:"(tap below for options)"}
+ ]
+ },
+ {kind: "onyx.Groupbox", ontap:"toggleSettings", components: [
+ {kind: "onyx.GroupboxHeader", content: "Events"},
+ {name: "eventList", style:"font-size:12px;", onDone:"removeEvent", components: [
+ {name:"waiting", content: "Waiting for events...", style:"padding:4px;font-style:italic;color:gray;"}
+ ]}
+ ]},
+ {ontap:"toggleSettings", name:"settings", showing:false, components: [
+ {kind: "onyx.Groupbox", classes:"gesture-sample-padded", components: [
+ {kind: "onyx.GroupboxHeader", content: "Options"},
+ {classes:"gesture-sample-setting", components: [
+ {content:"Truncate detail on small screen: "},
+ {name:"truncateDetail", onchange:"truncateChanged", ontap:"preventDefault", kind:"onyx.Checkbox", checked:true}
+ ]},
+ {classes:"gesture-sample-setting", style:"min-height:40px;", components: [
+ {content:"Monitor event: "},
+ {kind:"onyx.PickerDecorator", ontap:"preventDefault", onSelect:"monitorEventSelected", components: [
+ {content:"Select event", style:"width:140px; margin-bottom:5px;"},
+ {name:"eventPicker", kind:"onyx.Picker", classes:"gesture-sample-left"}
+ ]}
+ ]}
+ ]}
+ ]}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.eventList = {};
+ this.eventCount = 0;
+ enyo.forEach(["All events","down","up","tap","move","enter","leave","dragstart","drag","dragover","hold","release","holdpulse","flick","gesturestart","gesturechange","gestureend"], enyo.bind(this, function(event) {
+ this.$.eventPicker.createComponent({content:event, style:"text-align:left"});
+ }));
+ },
+ handleEvent: function(inSender, inEvent) {
+ var event = enyo.clone(inEvent);
+ if (this.monitorEvent && (event.type != this.monitorEvent)) {
+ return true;
+ }
+ var eventItem = this.eventList[event.type];
+ if (eventItem) {
+ eventItem.setEvent(event);
+ } else {
+ this.eventCount++;
+ eventItem = this.$.eventList.createComponent({
+ kind: "enyo.sample.EventItem",
+ event:event,
+ truncate: this.$.truncateDetail.getValue(),
+ persist: this.monitorEvent
+ });
+ this.eventList[event.type] = eventItem;
+ }
+ eventItem.render();
+ this.$.waiting.hide();
+ this.reflow();
+ return true;
+ },
+ truncateChanged: function() {
+ for (var i in this.eventList) {
+ this.eventList[i].setTruncate(this.$.truncateDetail.getValue());
+ }
+ this.reflow();
+ return false;
+ },
+ removeEvent: function(inSender, inEvent) {
+ this.eventCount--;
+ this.eventList[inEvent.type].destroy();
+ delete this.eventList[inEvent.type];
+ if (this.eventCount === 0) {
+ this.$.waiting.show();
+ }
+ this.reflow();
+ return true;
+ },
+ removeAllEvents: function() {
+ for (var i in this.eventList) {
+ this.eventList[i].destroy();
+ delete this.eventList[i];
+ }
+ this.eventCount = 0;
+ this.$.waiting.show();
+ this.reflow();
+ },
+ toggleSettings: function() {
+ this.$.settings.setShowing(!this.$.settings.getShowing());
+ this.reflow();
+ },
+ preventDefault: function() {
+ return true;
+ },
+ monitorEventSelected: function(inSender, inEvent) {
+ this.removeAllEvents();
+ if (inEvent.originator.content == "All events") {
+ this.monitorEvent = null;
+ } else {
+ this.monitorEvent = inEvent.originator.content;
+ }
+ }
+});
+
+enyo.kind({
+ name:"enyo.sample.EventItem",
+ published: {
+ event:"",
+ truncate: true,
+ persist: false
+ },
+ style:"padding:4px;",
+ events: {
+ onDone:""
+ },
+ components: [
+ {name:"eventProps", allowHtml:true},
+ {kind:"Animator", duration:1000, startValue:0, endValue:255, onStep:"stepAnimation", onEnd:"animationEnded"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.eventChanged();
+ this.truncateChanged();
+ },
+ truncateChanged: function() {
+ this.$.eventProps.addRemoveClass("gesture-sample-truncate", this.truncate);
+ },
+ // since event is an object, force set
+ setEvent: function(inEvent) {
+ this.setPropertyValue("event", inEvent, "eventChanged");
+ },
+ eventChanged: function(inOld) {
+ if (this.event) {
+ if (this.timeout) {
+ clearTimeout(this.timeout);
+ this.timeout = null;
+ }
+ this.$.animator.stop();
+ this.$.eventProps.setContent(this.getPropsString());
+ this.$.animator.play();
+ }
+ },
+ stepAnimation: function(inSender, inEvent) {
+ var v = Math.floor(inSender.value);
+ this.applyStyle("background-color", "rgb(" + v + ",255," + v + ");");
+ },
+ animationEnded: function() {
+ if (!this.persist) {
+ this.timeout = setTimeout(enyo.bind(this, function() {
+ this.doDone({type:this.event.type});
+ }), 2000);
+ }
+ },
+ destroy: function() {
+ if (this.timeout) {
+ clearTimeout(this.timeout);
+ this.timeout = null;
+ }
+ this.inherited(arguments);
+ },
+ getPropsString: function() {
+ var props = [];
+ for (var i in this.event) {
+ if ((this.event[i] !== undefined) &&
+ (this.event[i] !== null) &&
+ !(this.event[i] instanceof Object) &&
+ (i != "type")) {
+ props.push(i + ": " + this.event[i]);
+ }
+ }
+ if (this.event.srcEvent && this.event.srcEvent.type) {
+ props.push("srcEvent.type: " + this.event.srcEvent.type);
+ }
+ return "<b>" + this.event.type + "</b>: { " + props.join(", ") + " }";
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesJsonpSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/JsonpSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/JsonpSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/JsonpSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+.jsonp-sample {
+ padding: 15px;
+}
+
+.jsonp-sample-source {
+ padding:15px;
+ font-family: monospace;
+ font-size: 12px;
+ white-space: pre-wrap;
+ box-sizing: border-box;
+ width:100%;
+ height:100%;
+ margin-top:15px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesJsonpSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/JsonpSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/JsonpSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/JsonpSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <title>JSON-P Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../lib/layout/package.js" type="text/javascript"></script>
+ <script src="../../lib/onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="JsonpSample.css" rel="stylesheet">
+ <script src="JsonpSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body class="onyx">
+<script type="text/javascript">
+ new enyo.sample.JsonpSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesJsonpSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/JsonpSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/JsonpSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/JsonpSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.JsonpSample",
+ kind: "FittableRows",
+ classes: "enyo-fit jsonp-sample",
+ components: [
+ {kind: "FittableColumns", classes:"onyx-toolbar-inline", components: [
+ {content: "YQL: "},
+ {kind: "onyx.Input", name:"query", fit:true, value:'select * from upcoming.events where woeid in (select woeid from geo.places where text="Sunnyvale, CA")'},
+ {kind: "onyx.Button", content:"Fetch", ontap:"fetch"}
+ ]},
+ {kind: "onyx.TextArea", fit:true, classes:"jsonp-sample-source"}
+ ],
+ fetch: function() {
+ var jsonp = new enyo.JsonpRequest({
+ url: "http://query.yahooapis.com/v1/public/yql?format=json",
+ callbackName: "callback"
+ });
+ // send parameters the remote service using the 'go()' method
+ jsonp.go({
+ q: this.$.query.getValue()
+ });
+ // attach responders to the transaction object
+ jsonp.response(this, "processResponse");
+ },
+ processResponse: function(inSender, inResponse) {
+ // do something with it
+ this.$.textArea.setValue(JSON.stringify(inResponse, null, 2));
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesPlatformSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/PlatformSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/PlatformSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/PlatformSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+.platform-sample {
+ padding: 15px;
+}
+.platform-sample-divider {
+ color: #F49200;
+ text-transform: uppercase;
+ font-family: Segoe UI, Prelude Medium, Helvetica, Verdana, sans-serif;
+ font-size: 14px;
+ font-weight: bold;
+ margin-bottom: 8px;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesPlatformSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/PlatformSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/PlatformSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/PlatformSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <title>Platform Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../lib/layout/package.js" type="text/javascript"></script>
+ <script src="../../lib/onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="PlatformSample.css" rel="stylesheet">
+ <script src="PlatformSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body class="onyx">
+<script type="text/javascript">
+ new enyo.sample.PlatformSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesPlatformSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/PlatformSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/PlatformSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/PlatformSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.PlatformSample",
+ kind: "FittableRows",
+ classes: "enyo-fit platform-sample",
+ components: [
+ {classes: "platform-sample-divider", content: "Enyo Platform Detection"},
+ {kind: "onyx.Groupbox", components: [
+ {kind: "onyx.GroupboxHeader", content: "User-Agent String"},
+ {name: "uaString", content: "", style: "padding: 8px;"}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", components: [
+ {kind: "onyx.GroupboxHeader", content: "Window"},
+ {name: "windowAttr", content: "", style: "padding: 8px;"}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", components: [
+ {kind: "onyx.GroupboxHeader", content: "enyo.platform"},
+ {name: "enyoPlatformJSON", content: "", style: "padding: 8px;"}
+ ]}
+ ],
+ updateWindowSize: function() {
+ this.$.windowAttr.setContent("size: " + window.innerWidth + "x" + window.innerHeight +
+ ", devicePixelRatio: " + window.devicePixelRatio);
+ },
+ create: function() {
+ this.inherited(arguments);
+ this.$.uaString.setContent(navigator.userAgent);
+ this.$.enyoPlatformJSON.setContent(JSON.stringify(enyo.platform, null, 1));
+ this.updateWindowSize();
+ },
+ resizeHandler: function() {
+ this.inherited(arguments);
+ this.updateWindowSize();
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesPlaygroundcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/Playground.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/Playground.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/Playground.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+.playground-sample-player {
+ padding: 15px;
+}
+
+.playground-sample-source {
+ padding:15px;
+ font-family: monospace;
+ font-size: 12px;
+ white-space: pre-wrap;
+ box-sizing: border-box;
+ width:100%;
+ height:100%;
+}
+
+.playground-sample-panels > * {
+ width:320px;
+ box-shadow: -4px 0px 4px rgba(0,0,0,0.3);
+ -moz-box-shadow: -4px 0px 4px rgba(0,0,0,0.3);
+ -webkit-box-shadow: -4px 0px 4px rgba(0,0,0,0.3);
+}
+
+.sample-output {
+ min-height: 200px;
+ border: 1px solid black;
+ margin: 10px;
+ padding: 10px;
+ border-radius: 10px;
+ text-align: center;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesPlaygroundhtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/Playground.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/Playground.html (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/Playground.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <title>Enyo Playground</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../lib/canvas/package.js" type="text/javascript"></script>
+ <script src="../../lib/layout/package.js" type="text/javascript"></script>
+ <script src="../../lib/onyx/package.js" type="text/javascript"></script>
+ <script src="../../lib/extra/exampler/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="Playground.css" rel="stylesheet">
+ <script src="Playground.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body class="onyx">
+<script type="text/javascript">
+ new enyo.sample.Playground().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesPlaygroundjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/Playground.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/Playground.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/Playground.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.Playground",
+ kind: "Panels",
+ classes: "enyo-fit onyx playground-sample-panels",
+ arrangerKind:"CollapsingArranger",
+ components: [
+ {kind: "FittableRows", style:"width:50%;", components: [
+ {kind: "onyx.Toolbar", name:"toolbar", layoutKind:"FittableColumnsLayout", components: [
+ {content: "Enyo Playground", fit:true},
+ {kind: "onyx.PickerDecorator", components: [
+ {},
+ {kind: "onyx.Picker", floating:true, onChange:"sampleChanged", components: [
+ {content:"Sample1", active:true},
+ {content:"Sample2"},
+ {content:"Sample3"},
+ {content:"Sample4"}
+ ]}
+ ]}
+ ]},
+ {fit:true, style:"padding:15px;", components: [
+ {kind: "CodeEditor", fit:true, classes:"playground-sample-source"},
+ ]},
+ {kind: "FittableColumns", style:"margin:0px 15px 15px 15px", components: [
+ {fit:true}, // spacer
+ {kind: "onyx.Button", content: "Render Kind", ontap: "go"}
+ ]}
+ ]},
+ {kind: "FittableRows", classes:"onyx", components: [
+ {kind: "onyx.Toolbar", components: [
+ {kind: "onyx.Grabber"},
+ {content: "Result"}
+ ]},
+ {kind: "Scroller", fit:true, components: [
+ {kind: "CodePlayer", fit:true, classes: "playground-sample-player"}
+ ]}
+ ]}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ },
+ sampleChanged: function(inSender, inEvent) {
+ this.loadSample(inEvent.selected.content);
+ this.$.toolbar.resized();
+ },
+ loadSample: function(inSample) {
+ this.$.codeEditor.setUrl("assets/" + inSample + ".js");
+ },
+ go: function() {
+ this.$.codePlayer.go(this.$.codeEditor.getValue());
+ if (enyo.Panels.isScreenNarrow()) {
+ this.next();
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesRepeaterSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/RepeaterSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/RepeaterSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/RepeaterSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+.repeater-sample {
+ padding:15px;
+}
+.repeater-sample-item {
+ padding:4px;
+ margin:2px;
+ border:1px solid gray;
+ background-color: lightgray;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesRepeaterSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/RepeaterSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/RepeaterSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/RepeaterSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <title>Repeater Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../lib/layout/package.js" type="text/javascript"></script>
+ <script src="../../lib/onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="RepeaterSample.css" rel="stylesheet">
+ <script src="RepeaterSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body class="onyx">
+<script type="text/javascript">
+ new enyo.sample.RepeaterSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesRepeaterSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/RepeaterSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/RepeaterSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/RepeaterSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.RepeaterSample",
+ classes: "enyo-fit repeater-sample",
+ components: [
+ {kind: "Repeater", onSetupItem:"setupItem", components: [
+ {name:"item", classes:"repeater-sample-item", components: [
+ {tag:"span", name: "personNumber"},
+ {tag:"span", name: "personName"}
+ ]}
+ ]}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.$.repeater.setCount(this.people.length);
+ },
+ setupItem: function(inSender, inEvent) {
+ var index = inEvent.index;
+ var item = inEvent.item;
+ var person = this.people[index];
+ item.$.personNumber.setContent((index+1) + ". ");
+ item.$.personName.setContent(person.name);
+ item.$.personName.applyStyle("color", person.sex == "male" ? "dodgerblue" : "deeppink");
+ },
+ people: [
+ {name: "Andrew", sex:"male"},
+ {name: "Betty", sex:"female"},
+ {name: "Christopher", sex:"male"},
+ {name: "Donna", sex:"female"},
+ {name: "Ephraim", sex:"male"},
+ {name: "Frankie", sex:"male"},
+ {name: "Gerald", sex:"male"},
+ {name: "Heather", sex:"female"},
+ {name: "Ingred", sex:"female"},
+ {name: "Jack", sex:"male"},
+ {name: "Kevin", sex:"male"},
+ {name: "Lucy", sex:"female"},
+ {name: "Matthew", sex:"male"},
+ {name: "Noreen", sex:"female"},
+ {name: "Oscar", sex:"male"},
+ {name: "Pedro", sex:"male"},
+ {name: "Quentin", sex:"male"},
+ {name: "Ralph", sex:"male"},
+ {name: "Steven", sex:"male"},
+ {name: "Tracy", sex:"female"},
+ {name: "Uma", sex:"female"},
+ {name: "Victor", sex:"male"},
+ {name: "Wendy", sex:"female"},
+ {name: "Xin", sex:"male"},
+ {name: "Yulia", sex:"female"},
+ {name: "Zoltan"}
+ ]
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesScrollerSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/ScrollerSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/ScrollerSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/ScrollerSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+.scroller-sample-panels {
+ margin:15px;
+}
+.scroller-sample-content {
+ width:4000px;
+}
+.scroller-sample-scroller {
+ border: 1px solid orange;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesScrollerSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/ScrollerSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/ScrollerSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/ScrollerSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <title>Scroller Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../lib/layout/package.js" type="text/javascript"></script>
+ <script src="../../lib/onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="ScrollerSample.css" rel="stylesheet">
+ <script src="ScrollerSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body class="onyx">
+<script type="text/javascript">
+ new enyo.sample.ScrollerSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesScrollerSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/ScrollerSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/ScrollerSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/ScrollerSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.ScrollerSample",
+ kind: "FittableRows",
+ classes: "enyo-fit enyo-unselectable",
+ components: [
+ {kind: "onyx.Toolbar", components: [
+ {kind: "onyx.PickerDecorator", components: [
+ {content:"Choose Scroller", style:"width:250px;"},
+ {kind: "onyx.Picker", floating:true, maxHeight: 300, onSelect:"sampleChanged", components: [
+ {content:"Default scroller", active:true},
+ {content:"Force touch scroller"},
+ {content:"Horizontal only"},
+ {content:"Vertical only"},
+ {content:"Force TouchScrollStrategy"},
+ {content:"Force TransitionScrollStrategy"},
+ {content:"Force TranslateScrollStrategy"}
+ ]}
+ ]}
+ ]},
+ {kind: "Panels", fit: true, draggable: false, classes: "scroller-sample-panels", components: [
+ // Default scroller (chooses best scrolling method for platform)
+ {kind: "Scroller", classes: "scroller-sample-scroller enyo-fit"},
+ // Forces touch scrolling, even on desktop
+ {kind: "Scroller", touch:true, classes: "scroller-sample-scroller enyo-fit"},
+ // Horizontal-only scrolling
+ {kind: "Scroller", vertical:"hidden", classes: "scroller-sample-scroller enyo-fit"},
+ // Vertical-only scrolling
+ {kind: "Scroller", horizontal:"hidden", classes: "scroller-sample-scroller enyo-fit", onmousedown: "mouseDown", ondragstart: "dragStart"},
+ // Force specific strategies
+ {kind: "Scroller", classes: "scroller-sample-scroller enyo-fit", strategyKind: "TouchScrollStrategy"},
+ {kind: "Scroller", classes: "scroller-sample-scroller enyo-fit", strategyKind: "TransitionScrollStrategy"},
+ {kind: "Scroller", classes: "scroller-sample-scroller enyo-fit", strategyKind: "TranslateScrollStrategy"}
+ ]}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ var scrollers = this.$.panels.getPanels();
+ for (var i in scrollers) {
+ scrollers[i].createComponent({
+ allowHtml:true,
+ content:this.text,
+ classes:"scroller-sample-content"
+ });
+ }
+ },
+ sampleChanged: function(inSender, inEvent) {
+ this.$.panels.setIndex(inEvent.selected.indexInContainer()-1);
+ },
+ text: "Foo<br>Bar<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>Boom boom pow<br>" +
+ "Foo<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>Boom boom pow. Boom boom pow. " +
+ "Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. " +
+ "Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. " +
+ "Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. <br>Foo<br>Bar<br>Bar<br>" +
+ "Boom boom pow<br>Foo<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>Boom boom pow<br>" +
+ "Foo<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. " +
+ "Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. " +
+ "Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. " +
+ "Boom boom pow. Boom boom pow. Boom boom pow. <br>Foo<br>Bar<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>" +
+ "Boom boom pow<br>Foo<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>Boom boom pow<br>" +
+ "Foo<br>Bar<br>Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. " +
+ "Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. " +
+ "Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. " +
+ "Boom boom pow. <br>Foo<br>Bar<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>" +
+ "Boom boom pow<br>Foo<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>Boom boom pow<br>Foo<br>Bar<br>Boom boom pow. " +
+ "Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. " +
+ "Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. " +
+ "Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. Boom boom pow. <br>",
+ // The following are used when this sample is called from the Sampler app
+ mouseDown: function(inSender, inEvent) {
+ inEvent.preventDefault();
+ },
+ dragStart: function(inSender, inEvent) {
+ if (inEvent.horizontal) {
+ // Prevent drag propagation on horizontal drag events
+ return true;
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesWebServiceSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/WebServiceSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/WebServiceSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/WebServiceSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+.webservice-sample {
+ padding: 15px;
+}
+
+.webservice-sample-source {
+ padding:15px;
+ font-family: monospace;
+ font-size: 12px;
+ white-space: pre-wrap;
+ box-sizing: border-box;
+ width:100%;
+ height:100%;
+ margin-top:15px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesWebServiceSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/WebServiceSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/WebServiceSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/WebServiceSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <title>WebService Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../lib/layout/package.js" type="text/javascript"></script>
+ <script src="../../lib/onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="WebServiceSample.css" rel="stylesheet">
+ <script src="WebServiceSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body class="onyx">
+<script type="text/javascript">
+ new enyo.sample.WebServiceSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesWebServiceSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/WebServiceSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/WebServiceSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/WebServiceSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.WebServiceSample",
+ kind: "FittableRows",
+ classes: "enyo-fit webservice-sample",
+ components: [
+ {kind: "WebService", name:"yql", url: "http://query.yahooapis.com/v1/public/yql?format=json", onResponse:"processResponse", callbackName: "callback"},
+ {kind: "FittableColumns", classes:"onyx-toolbar-inline", components: [
+ {content: "YQL: "},
+ {kind: "onyx.Input", name:"query", fit:true, value:'select * from upcoming.events where woeid in (select woeid from geo.places where text="Sunnyvale, CA")'},
+ {kind: "onyx.PickerDecorator", components: [
+ {content:"Choose Scroller", style:"width:100px;"},
+ {kind: "onyx.Picker", floating:true, components: [
+ {content:"AJAX", active:true},
+ {content:"JSON-P"}
+ ]}
+ ]},
+ {kind: "onyx.Button", content:"Fetch", ontap:"fetch"}
+ ]},
+ {kind: "onyx.TextArea", fit:true, classes:"webservice-sample-source"}
+ ],
+ fetch: function() {
+ // send parameters the remote service using the 'send()' method
+ this.$.yql.send({
+ q: this.$.query.getValue(),
+ jsonp: (this.$.picker.getSelected().indexInContainer()==2)
+ });
+ },
+ processResponse: function(inSender, inEvent) {
+ // do something with it
+ this.$.textArea.setValue(JSON.stringify(inEvent.data, null, 2));
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesassetsSample1js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/assets/Sample1.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/assets/Sample1.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/assets/Sample1.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+enyo.kind({
+ name: "Sample",
+ kind: "Control",
+ components: [
+ {name: "input", tag: "input"},
+ {tag: "br"},
+ {name: "button", tag: "button", content: "Set Content", ontap: "buttonTap"},
+ {tag: "br"},
+ {name: "output", classes: "sample-output"}
+ ],
+ buttonTap: function(inSender, inEvent) {
+ var value = this.$.input.hasNode().value;
+ this.$.output.setContent(value);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesassetsSample2js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/assets/Sample2.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/assets/Sample2.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/assets/Sample2.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+enyo.kind({
+ name: "Sample",
+ kind: "Control",
+ components: [
+ {name: "input", tag: "input", attributes: {value: "red"}},
+ {tag: "br"},
+ {tag: "button", content: "Set Color", ontap: "buttonTap"},
+ {tag: "br"},
+ {name: "output", classes: "sample-output"}
+ ],
+ buttonTap: function(inSender, inEvent) {
+ var color = this.$.input.hasNode().value;
+ this.$.output.applyStyle("background", color);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesassetsSample3js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/assets/Sample3.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/assets/Sample3.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/assets/Sample3.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+enyo.kind({
+ name: "Sample",
+ kind: "Control",
+ components: [
+ {name: "input", tag: "input", attributes: {value: "Foo "}},
+ {tag: "br"},
+ {tag: "button", content: "Add Content", ontap: "addContentTap"},
+ {tag: "br"},
+ {tag: "button", style: "margin-right: .5em;", content: "Hide", ontap: "hideTap"},
+ {tag: "button", style: "margin-right: .5em;", content: "Show", ontap: "showTap"},
+ {tag: "button", content: "Toggle class", ontap: "toggleClassTap"},
+ {tag: "br"},
+ {name: "output", classes: "sample-output"}
+ ],
+ addContentTap: function(inSender, inEvent) {
+ var content = this.$.input.hasNode().value;
+ this.$.output.addContent(content);
+ },
+ hideTap: function(inSender, inEvent) {
+ this.$.output.hide();
+ },
+ showTap: function(inSender, inEvent) {
+ this.$.output.show();
+ },
+ toggleClassTap: function(inSender, inEvent) {
+ var c = "sample-output";
+ var has = this.$.output.hasClass(c);
+ this.$.output.addRemoveClass(c, !has);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplesassetsSample4js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/assets/Sample4.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/assets/Sample4.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/assets/Sample4.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+enyo.kind({
+ name: "Sample",
+ kind: "Control",
+ components: [
+ {content: "Create a button control with the given content:", style: "padding: 10px 0;"},
+ {name: "input", tag: "input", attributes: {value: "Foo"}, style: "display: block;"},
+ {style: "padding: 10px 0;", components: [
+ {tag: "button", style: "margin-right: 10px;", content: "Add", ontap: "addTap"},
+ {tag: "button", content: "Clear", ontap: "clearTap"},
+ ]},
+ {name: "output"}
+ ],
+ addTap: function(inSender, inEvent) {
+ var content = this.$.input.hasNode().value;
+ this.createComponent({
+ tag: "button",
+ content: content,
+ container: this.$.output
+ }).render();
+ },
+ clearTap: function(inSender, inEvent) {
+ this.$.output.destroyClientControls();
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosamplespackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/samples/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/samples/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/samples/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+enyo.depends(
+ "$lib/extra/exampler",
+ "PlatformSample.css",
+ "PlatformSample.js",
+ "Playground.css",
+ "Playground.js",
+ "AjaxSample.css",
+ "AjaxSample.js",
+ "JsonpSample.css",
+ "JsonpSample.js",
+ "WebServiceSample.css",
+ "WebServiceSample.js",
+ "RepeaterSample.css",
+ "RepeaterSample.js",
+ "ScrollerSample.css",
+ "ScrollerSample.js",
+ "GestureSample.css",
+ "GestureSample.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceajaxAjaxjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ajax/Ajax.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ajax/Ajax.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ajax/Ajax.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,255 @@
</span><ins>+/**
+ _enyo.Ajax_ is a wrapper for _XmlHttpRequest_ that uses
+ the <a href="#enyo.Async">enyo.Async</a> API.
+
+ _enyo.Ajax_ publishes all the properties of the
+ <a href="#enyo.AjaxProperties">enyo.AjaxProperties</a>
+ object.
+
+ Like _enyo.Async_, _enyo.Ajax_ is an **Object**, not a **Component**.
+ Do not try to make _enyo.Ajax_ objects inside a _components_ block.
+ If you want to use _enyo.Ajax_ as a component, you should probably
+ be using <a href="#enyo.WebService">enyo.WebService</a> instead.
+
+ If you make changes to _enyo.Ajax_, be sure to add or update the appropriate
+ [unit tests](https://github.com/enyojs/enyo/tree/master/tools/test/ajax/tests).
+
+ For more information, see the documentation on
+ [Consuming Web Services](https://github.com/enyojs/enyo/wiki/Consuming-Web-Services)
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.Ajax",
+ kind: enyo.Async,
+ //* See <a href="#enyo.AjaxProperties">enyo.AjaxProperties</a> for the list of properties
+ //* published by _enyo.Ajax_.
+ published: enyo.AjaxProperties,
+ //* @protected
+ constructor: function(inParams) {
+ enyo.mixin(this, inParams);
+ this.inherited(arguments);
+ },
+ //* @public
+ /**
+ Sends the Ajax request with parameters _inParams_. _inParams_ values may be
+ either Strings or Objects.
+
+ _inParams_ as an Object is converted into the url query string. For
+ instance, passing <code>{q: "searchTerm"}</code> will result in the addition
+ of the string `q="searchTerm"` to the current url query string.
+
+ _inParams_ as a String is used as the query part of the URL directly.
+
+ _inParams_ will not be converted into a POST body, it will always be used as
+ part of the URL query string if provided. Use the `postBody` property for
+ specifying a body.
+
+ When the request is completed, the code will set a `xhrResponse` property
+ in the `enyo.Ajax` object with the subproperties `status`, `headers`, and
+ `body`. These cache the results from the XHR for later use. The keys for
+ the `headers` object have been converted to all lower case as HTTP headers
+ are case-insensitive.
+ */
+ go: function(inParams) {
+ this.startTimer();
+ this.request(inParams);
+ return this;
+ },
+ //* @protected
+ request: function(inParams) {
+ var parts = this.url.split("?");
+ var uri = parts.shift() || "";
+ var args = parts.length ? (parts.join("?").split("&")) : [];
+ //
+ var query = null;
+ //
+ if(enyo.isString(inParams)){
+ //If inParams parameter is a string, use it as request body
+ query = inParams;
+ }
+ else{
+ //If inParams parameter is not a string, build a query from it
+ if(inParams){
+ query = enyo.Ajax.objectToQuery(inParams);
+ }
+ }
+ //
+ if (query) {
+ args.push(query);
+ query = null;
+ }
+ if (this.cacheBust) {
+ args.push(Math.random());
+ }
+ //
+ var url = args.length ? [uri, args.join("&")].join("?") : uri;
+ //
+ var xhr_headers = {};
+ var body;
+ if (this.method != "GET") {
+ body = this.postBody;
+ if (this.method === "POST" && body instanceof enyo.FormData) {
+ if (body.fake) {
+ xhr_headers["Content-Type"] = body.getContentType();
+ body = body.toString();
+ } else {
+ // Nothing to do as the
+ // content-type will be
+ // automagically set according
+ // to the FormData
+ }
+ } else {
+ xhr_headers["Content-Type"] = this.contentType;
+ if (body instanceof Object) {
+ if (this.contentType === "application/json") {
+ body = JSON.stringify(body);
+ } else if (this.contentType === "application/x-www-form-urlencoded") {
+ body = enyo.Ajax.objectToQuery(body);
+ }
+ else {
+ body = body.toString();
+ }
+ }
+ }
+ }
+ enyo.mixin(xhr_headers, this.headers);
+ // don't pass in headers structure if there are no headers defined as this messes
+ // up CORS code for IE8-9
+ if (enyo.keys(xhr_headers).length === 0) {
+ xhr_headers = undefined;
+ }
+ //
+ try {
+ this.xhr = enyo.xhr.request({
+ url: url,
+ method: this.method,
+ callback: enyo.bind(this, "receive"),
+ body: body,
+ headers: xhr_headers,
+ sync: window.PalmSystem ? false : this.sync,
+ username: this.username,
+ password: this.password,
+ xhrFields: this.xhrFields,
+ mimeType: this.mimeType
+ });
+ }
+ catch (e) {
+ // IE can throw errors here if the XHR would fail CORS checks,
+ // so catch and turn into a failure.
+ this.fail(e);
+ }
+ },
+ receive: function(inText, inXhr) {
+ if (!this.failed && !this.destroyed) {
+ var body;
+ if (typeof inXhr.responseText === "string") {
+ body = inXhr.responseText;
+ } else {
+ // IE carrying a binary
+ body = inXhr.responseBody;
+ }
+ this.xhrResponse = {
+ status: inXhr.status,
+ headers: enyo.Ajax.parseResponseHeaders(inXhr),
+ body: body
+ };
+ if (this.isFailure(inXhr)) {
+ this.fail(inXhr.status);
+ } else {
+ this.respond(this.xhrToResponse(inXhr));
+ }
+ }
+ },
+ fail: function(inError) {
+ // on failure, explicitly cancel the XHR to prevent
+ // further responses. cancellation also resets the
+ // response headers & body,
+ if (this.xhr) {
+ enyo.xhr.cancel(this.xhr);
+ this.xhr = null;
+ }
+ this.inherited(arguments);
+ },
+ xhrToResponse: function(inXhr) {
+ if (inXhr) {
+ return this[(this.handleAs || "text") + "Handler"](inXhr);
+ }
+ },
+ isFailure: function(inXhr) {
+ // if any exceptions are thrown while checking fields in the xhr,
+ // assume a failure.
+ try {
+ var text = "";
+ // work around IE8-9 bug where accessing responseText will thrown error
+ // for binary requests.
+ if (typeof inXhr.responseText === "string") {
+ text = inXhr.responseText;
+ }
+ // Follow same failure policy as jQuery's Ajax code
+ // CORS failures on FireFox will have status 0 and no responseText,
+ // so treat that as failure.
+ if (inXhr.status === 0 && text === "") {
+ return true;
+ }
+ // Otherwise, status 0 may be good for local file access. We treat the range
+ // 1-199 and 300+ as failure (only 200-series code are OK).
+ return (inXhr.status !== 0) && (inXhr.status < 200 || inXhr.status >= 300);
+ }
+ catch (e) {
+ return true;
+ }
+ },
+ xmlHandler: function(inXhr) {
+ return inXhr.responseXML;
+ },
+ textHandler: function(inXhr) {
+ return inXhr.responseText;
+ },
+ jsonHandler: function(inXhr) {
+ var r = inXhr.responseText;
+ try {
+ return r && enyo.json.parse(r);
+ } catch (x) {
+ enyo.warn("Ajax request set to handleAs JSON but data was not in JSON format");
+ return r;
+ }
+ },
+ statics: {
+ objectToQuery: function(/*Object*/ map) {
+ var enc = encodeURIComponent;
+ var pairs = [];
+ var backstop = {};
+ for (var name in map){
+ var value = map[name];
+ if (value != backstop[name]) {
+ var assign = enc(name) + "=";
+ if (enyo.isArray(value)) {
+ for (var i=0; i < value.length; i++) {
+ pairs.push(assign + enc(value[i]));
+ }
+ } else {
+ pairs.push(assign + enc(value));
+ }
+ }
+ }
+ return pairs.join("&");
+ },
+ parseResponseHeaders: function(xhr) {
+ var headers = {};
+ var headersStr = [];
+ if (xhr.getAllResponseHeaders) {
+ headersStr = xhr.getAllResponseHeaders().split(/\r?\n/);
+ }
+ for (var i = 0; i < headersStr.length; i++) {
+ var headerStr = headersStr[i];
+ var index = headerStr.indexOf(': ');
+ if (index > 0) {
+ var key = headerStr.substring(0, index).toLowerCase();
+ var val = headerStr.substring(index + 2);
+ headers[key] = val;
+ }
+ }
+ return headers;
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceajaxAjaxPropertiesjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ajax/AjaxProperties.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ajax/AjaxProperties.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ajax/AjaxProperties.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,68 @@
</span><ins>+/**
+ Common set of published properties used in both
+ <a href="#enyo.Ajax">enyo.Ajax</a> and
+ <a href="#enyo.WebService">enyo.WebService</a>.
+*/
+enyo.AjaxProperties = {
+ /**
+ When true, appends a random number as a parameter for GET requests
+ to try to force a new fetch of the resource instead of reusing a local cache.
+ */
+ cacheBust: true,
+ /**
+ The URL for the service. This can be a relative URL if used to fetch resources bundled with the application.
+ */
+ url: "",
+ /**
+ The HTTP method to use for the request, defaults to GET. Supported values include
+ "GET", "POST", "PUT", and "DELETE".
+ */
+ method: "GET", // {value: "GET", options: ["GET", "POST", "PUT", "DELETE"]},
+ /**
+ How the response will be handled.
+ Supported values are: <code>"json", "text", "xml"</code>
+ */
+ handleAs: "json", // {value: "json", options: ["text", "json", "xml"]},
+ /**
+ The Content-Type header for the request as a String.
+ */
+ contentType: "application/x-www-form-urlencoded",
+ /**
+ If true, makes a synchronous (blocking) call, if supported. Synchronous requests
+ are not supported on HP webOS.
+ */
+ sync: false,
+ /**
+ Optional additional request headers as a JS object, e.g.
+ <code>{ "X-My-Header": "My Value", "Mood": "Happy" }</code> or null.
+ */
+ headers: null,
+ /**
+ The content for the request body for POST/PUT methods.
+
+ When postBody is a Buffer or a String, it is passed verbatim in the request body.
+ When postBody is an Object, the way it is encoded depends on the contentType:
+
+ * application/json => JSON.stringify
+ * application/x-www-urlencoed => url-encoded parameters
+ * multipart/form-data => passed as fields in enyo.FormData (XHR2 emulation)
+ */
+ postBody: "",
+ /**
+ The optional user name to use for authentication purposes.
+ */
+ username: "",
+ /**
+ The optional password to use for authentication purposes.
+ */
+ password: "",
+ /**
+ Optional object with fields to pass directly to the underlying XHR object.
+ One example is the _withCredentials_ flag used for cross-origin requests.
+ */
+ xhrFields: null,
+ /**
+ Optional string to override the MIME-Type header.
+ */
+ mimeType: null
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceajaxAsyncjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ajax/Async.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ajax/Async.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ajax/Async.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,128 @@
</span><ins>+/**
+ _enyo.Async_ is the base kind for handling asynchronous operations.
+
+ _enyo.Async_ is an **Object**, not a **Component**; thus, you may not declare
+ an _Async_ in a _components_ block. If you want to use _Async_ as a
+ component, you should probably be using
+ <a href="#enyo.WebService">enyo.WebService</a> instead.
+
+ An Async object represents a task that has not yet completed. You may attach
+ callback functions to an Async, to be called when the task completes or
+ encounters an error.
+
+ More information on _Async_ and its usage is available in the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Consuming-Web-Services">Consuming Web Services</a>
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.Async",
+ kind: enyo.Object,
+ published: {
+ /**
+ If set to a non-zero value, the number of milliseconds to
+ wait after the _go_ call before failing with the "timeout" error
+ */
+ timeout: 0
+ },
+ //* @protected
+ failed: false,
+ context: null,
+ constructor: function() {
+ this.responders = [];
+ this.errorHandlers = [];
+ },
+ accumulate: function(inArray, inMethodArgs) {
+ var fn = (inMethodArgs.length < 2) ? inMethodArgs[0] : enyo.bind(inMethodArgs[0], inMethodArgs[1]);
+ inArray.push(fn);
+ },
+ //* @public
+ /**
+ Registers a response function.
+ First parameter is an optional _this_ context for the response method.
+ Second (or only) parameter is the function object.
+ */
+ response: function(/* [inContext], inResponder */) {
+ this.accumulate(this.responders, arguments);
+ return this;
+ },
+ /**
+ Registers an error handler.
+ First parameter is an optional _this_ context for the response method.
+ Second (or only) parameter is the function object.
+ */
+ error: function(/* [inContext], inResponder */) {
+ this.accumulate(this.errorHandlers, arguments);
+ return this;
+ },
+ //* @protected
+ route: function(inAsync, inValue) {
+ var r = enyo.bind(this, "respond");
+ inAsync.response(function(inSender, inValue) {
+ r(inValue);
+ });
+ var f = enyo.bind(this, "fail");
+ inAsync.error(function(inSender, inValue) {
+ f(inValue);
+ });
+ inAsync.go(inValue);
+ },
+ handle: function(inValue, inHandlers) {
+ var r = inHandlers.shift();
+ if (r) {
+ if (r instanceof enyo.Async) {
+ this.route(r, inValue);
+ } else {
+ // handler can return a new 'value'
+ var v = enyo.call(this.context || this, r, [this, inValue]);
+ // ... but only if it returns something other than undefined
+ v = (v !== undefined) ? v : inValue;
+ // next handler
+ (this.failed ? this.fail : this.respond).call(this, v);
+ }
+ }
+ },
+ startTimer: function() {
+ this.startTime = enyo.now();
+ if (this.timeout) {
+ this.timeoutJob = setTimeout(enyo.bind(this, "timeoutComplete"), this.timeout);
+ }
+ },
+ endTimer: function() {
+ if (this.timeoutJob) {
+ this.endTime = enyo.now();
+ clearTimeout(this.timeoutJob);
+ this.timeoutJob = null;
+ this.latency = this.endTime - this.startTime;
+ }
+ },
+ timeoutComplete: function() {
+ this.timedout = true;
+ this.fail("timeout");
+ },
+ //* @protected
+ //* Called as part of the async implementation; triggers the handler chain.
+ respond: function(inValue) {
+ this.failed = false;
+ this.endTimer();
+ this.handle(inValue, this.responders);
+ },
+ //* @public
+ //* Can be called from any handler to trigger the error chain.
+ fail: function(inError) {
+ this.failed = true;
+ this.endTimer();
+ this.handle(inError, this.errorHandlers);
+ },
+ //* Called from an error handler; clears the error condition and resumes
+ //* calling handler methods.
+ recover: function() {
+ this.failed = false;
+ },
+ //* Starts the async activity. Overridden in subkinds.
+ go: function(inValue) {
+ enyo.asyncMethod(this, function() {
+ this.respond(inValue);
+ });
+ return this;
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceajaxJsonpjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ajax/Jsonp.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ajax/Jsonp.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ajax/Jsonp.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,123 @@
</span><ins>+/**
+ _enyo.JsonpRequest_ is a specialized form of
+ <a href="#enyo.Async">enyo.Async</a> used for making JSONP requests to a
+ remote server. This differs from the normal XmlHTTPRequest call in that the
+ external resource is loaded using a <script> tag. This allows us to
+ bypass the same-domain rules that normally apply to XHR, since the browser
+ will load scripts from any address.
+
+ If you make changes to _enyo.JsonpRequest_, be sure to add or update the
+ appropriate [unit tests](https://github.com/enyojs/enyo/tree/master/tools/test/ajax/tests).
+
+ For more information, see the documentation on
+ [Consuming Web Services](https://github.com/enyojs/enyo/wiki/Consuming-Web-Services)
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.JsonpRequest",
+ kind: enyo.Async,
+ published: {
+ //* The URL for the service
+ url: "",
+ //* Optional character set to use to interpret the return data
+ charset: null,
+ /**
+ Name of the argument that holds the callback name. For example, the
+ Twitter search API uses "callback" as the parameter to hold the
+ name of the called function. We will automatically add this to
+ the encoded arguments.
+ */
+ callbackName: "callback",
+ /**
+ When true, appends a random number as a parameter for GET requests
+ to try to force a new fetch of the resource instead of reusing a
+ local cache
+ */
+ cacheBust: true
+ },
+ statics: {
+ // Counter to allow creation of unique name for each JSONP request
+ nextCallbackID: 0
+ },
+ //* @protected
+ addScriptElement: function() {
+ var script = document.createElement('script');
+ script.src = this.src;
+ script.async = "async";
+ if (this.charset) {
+ script.charset = this.charset;
+ }
+ // most modern browsers also have an onerror handler
+ script.onerror = enyo.bind(this, function() {
+ // we don't get an error code, so we'll just use the generic 400 error status
+ this.fail(400);
+ });
+ // add script before existing script to make sure it's in a valid part of document
+ // http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/
+ var first = document.getElementsByTagName('script')[0];
+ first.parentNode.insertBefore(script, first);
+ this.scriptTag = script;
+ },
+ removeScriptElement: function() {
+ var script = this.scriptTag;
+ this.scriptTag = null;
+ script.onerror = null;
+ if (script.parentNode) {
+ script.parentNode.removeChild(script);
+ }
+ },
+ constructor: function(inParams) {
+ enyo.mixin(this, inParams);
+ this.inherited(arguments);
+ },
+ //* @public
+ //* Starts the JSONP request.
+ go: function(inParams) {
+ this.startTimer();
+ this.jsonp(inParams);
+ return this;
+ },
+ //* @protected
+ jsonp: function(inParams) {
+ var callbackFunctionName = "enyo_jsonp_callback_" + (enyo.JsonpRequest.nextCallbackID++);
+ //
+ this.src = this.buildUrl(inParams, callbackFunctionName);
+ this.addScriptElement();
+ //
+ window[callbackFunctionName] = enyo.bind(this, this.respond);
+ //
+ // setup cleanup handlers for JSONP completion and failure
+ var cleanup = enyo.bind(this, function() {
+ this.removeScriptElement();
+ window[callbackFunctionName] = null;
+ });
+ this.response(cleanup);
+ this.error(cleanup);
+ },
+ buildUrl: function(inParams, inCallbackFunctionName) {
+ var parts = this.url.split("?");
+ var uri = parts.shift() || "";
+ var args = parts.join("?").split("&");
+ //
+ var bodyArgs = this.bodyArgsFromParams(inParams, inCallbackFunctionName);
+ args.push(bodyArgs);
+ if (this.cacheBust) {
+ args.push(Math.random());
+ }
+ //
+ return [uri, args.join("&")].join("?");
+ },
+ // for a string version of inParams, we follow the convention of
+ // replacing the string "=?" with the callback name. For the more
+ // common case of inParams being an object, we'll add a argument named
+ // using the callbackName published property.
+ bodyArgsFromParams: function(inParams, inCallbackFunctionName) {
+ if (enyo.isString(inParams)) {
+ return inParams.replace("=?", "=" + inCallbackFunctionName);
+ } else {
+ var params = enyo.mixin({}, inParams);
+ params[this.callbackName] = inCallbackFunctionName;
+ return enyo.Ajax.objectToQuery(params);
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceajaxWebServicejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ajax/WebService.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ajax/WebService.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ajax/WebService.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,114 @@
</span><ins>+//* @protected
+enyo.kind({
+ name: "enyo._AjaxComponent",
+ kind: enyo.Component,
+ published: enyo.AjaxProperties
+});
+
+//* @public
+/**
+ _enyo.WebService_ is a component that performs Web requests (_XmlHttpRequest_).
+
+ Internally, _enyo.WebService_ uses _enyo.Async_ subkinds (namely,
+ <a href="#enyo.Ajax">enyo.Ajax</a> and
+ <a href="#enyo.JsonpRequest">enyo.JsonpRequest</a>) to manage transactions.
+ The _send_ method returns the Async instance used by the request.
+
+ _enyo.WebService_ uses _enyo.Ajax_ by default and, like _enyo.Ajax_, it
+ publishes all the properties of the
+ <a href="#enyo.AjaxProperties">enyo.AjaxProperties</a> object.
+
+ To use `enyo.JsonpRequest` instead of `enyo.Ajax`, set `json` to `true`.
+
+ If you make changes to _enyo.WebService_, be sure to add or update the
+ appropriate [unit tests](https://github.com/enyojs/enyo/tree/master/tools/test/ajax/tests).
+
+ For more information, see the documentation on
+ [Consuming Web Services](https://github.com/enyojs/enyo/wiki/Consuming-Web-Services)
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.WebService",
+ kind: enyo._AjaxComponent,
+ published: {
+ //* Set to true to use JSONP protocol
+ jsonp: false,
+ /**
+ When using JSONP, the name of the callback parameter.
+ Note that this not the name of a callback function, but only
+ the name of the callback parameter. Enyo will create an
+ internal callback function as necessary.
+ */
+ callbackName: "callback",
+ /**
+ When using JSONP, optional character set to use to interpret the
+ return data
+ */
+ charset: null,
+ /**
+ If set to a non-zero value, the number of milliseconds to
+ wait after the _send_ call before failing with a "timeout" error
+ */
+ timeout: 0
+ },
+ events: {
+ /**
+ Fires when a response is received.
+
+ _inEvent.ajax_ contains the Async instance associated with the request.
+
+ _inEvent.data_ contains the response data.
+ */
+ onResponse: "",
+ /**
+ Fires when an error is received.
+
+ _inEvent.ajax_ contains the Async instance associated with the request.
+
+ _inEvent.data_ contains the error data.
+ */
+ onError: ""
+ },
+ //* @protected
+ constructor: function(inProps) {
+ this.inherited(arguments);
+ },
+ //* @public
+ /**
+ Sends a Web request with the passed-in parameters, returning the
+ associated Async instance.
+
+ _inProps_ is an optional object parameterthat can be used to override some
+ of the AJAX properties for this request, such as setting a _postBody_.
+ */
+ send: function(inParams, inProps) {
+ return this.jsonp ? this.sendJsonp(inParams, inProps) : this.sendAjax(inParams, inProps);
+ },
+ //* @protected
+ sendJsonp: function(inParams, inProps) {
+ var jsonp = new enyo.JsonpRequest();
+ for (var n in {'url':1, 'callbackName':1, 'charset':1, 'timeout':1}) {
+ jsonp[n] = this[n];
+ }
+ enyo.mixin(jsonp, inProps);
+ return this.sendAsync(jsonp, inParams);
+ },
+ sendAjax: function(inParams, inProps) {
+ var ajax = new enyo.Ajax(inProps);
+ for (var n in enyo.AjaxProperties) {
+ ajax[n] = this[n];
+ }
+ ajax.timeout = this.timeout;
+ enyo.mixin(ajax, inProps);
+ return this.sendAsync(ajax, inParams);
+ },
+ sendAsync: function(inAjax, inParams) {
+ return inAjax.go(inParams).response(this, "response").error(this, "error");
+ },
+ response: function(inSender, inData) {
+ this.doResponse({ajax: inSender, data: inData});
+ },
+ error: function(inSender, inData) {
+ this.doError({ajax: inSender, data: inData});
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceajaxcookiejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ajax/cookie.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ajax/cookie.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ajax/cookie.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+//* @public
+
+/**
+ Gets a named value from the document cookie.
+*/
+enyo.getCookie = function(inName) {
+ var matches = document.cookie.match(new RegExp("(?:^|; )" + inName + "=([^;]*)"));
+ return matches ? decodeURIComponent(matches[1]) : undefined;
+};
+
+/**
+ Sets a named value in the document cookie, with properties.
+
+ Properties in the optional _inProps_ argument are attached to the cookie.
+ _inProps_ may have an _expires_ property, which can be a number of days, a
+ Date object, or a UTC time string.
+
+ To remove a cookie, use an _inProps_ value of <code>{ "Max-Age": 0 }</code>.
+
+ If developing in the Google Chrome browser with a local file as your
+ application, start Chrome with the <code>--enable-file-cookies</code> switch
+ to allow cookies to be set.
+*/
+enyo.setCookie = function(inName, inValue, inProps) {
+ var cookie = inName + "=" + encodeURIComponent(inValue);
+ var p = inProps || {};
+ //
+ // FIXME: expires=0 seems to disappear right away, not on close? (FF3) Change docs?
+ var exp = p.expires;
+ if (typeof exp == "number") {
+ var d = new Date();
+ d.setTime(d.getTime() + exp*24*60*60*1000);
+ exp = d;
+ }
+ if (exp && exp.toUTCString) {
+ p.expires = exp.toUTCString();
+ }
+ //
+ var name, value;
+ for (name in p){
+ cookie += "; " + name;
+ value = p[name];
+ if (value !== true) {
+ cookie += "=" + value;
+ }
+ }
+ //
+ //enyo.log(cookie);
+ document.cookie = cookie;
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceajaxformdatajs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ajax/formdata.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ajax/formdata.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ajax/formdata.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,91 @@
</span><ins>+/**
+
+_enyo.FormData_ is an [XHR2](http://www.w3.org/TR/XMLHttpRequest/)
+`FormData` implementation. It is used to send `multipart/form-data`
+Ajax requests. _enyo.Blob_ is the associated content provider for
+file-parts.
+
+Note that in IE<10, both _enyo.FormData_ and _enyo.Blob_ are limited
+to `String` content--an _enyo.Blob_ may only be instantiated using an
+`Array` or `String`.
+
+_enyo.FormData_ is inspired by
+[html5-formdata](https://github.com/francois2metz/html5-formdata/blob/master/formdata.js).
+
+ Emulate FormData for some browsers
+ MIT License
+ (c) 2010 Francois de Metz
+
+ */
+(function(w) {
+ if (w.FormData) {
+ try {
+ var t1 = new w.FormData();
+ var t2 = new w.Blob();
+ // Android Chrome 18 will throw an error trying to create these
+ enyo.FormData = w.FormData;
+ enyo.Blob = w.Blob;
+ return;
+ }
+ catch (e) {
+ // ignore error and fall through to fake FormData code
+ }
+ }
+ function FormData() {
+ this.fake = true;
+ this._fields = [];
+ // This generates a 50 character boundary similar to
+ // those used by Firefox. They are optimized for
+ // boyer-moore parsing.
+ this.boundary = '--------------------------';
+ for (var i = 0; i < 24; i++) {
+ this.boundary += Math.floor(Math.random() * 10).toString(16);
+ }
+ }
+ FormData.prototype.getContentType = function() {
+ return "multipart/form-data; boundary=" + this.boundary;
+ };
+ FormData.prototype.append = function(key, value, filename) {
+ this._fields.push([key, value, filename]);
+ };
+ FormData.prototype.toString = function() {
+ var boundary = this.boundary;
+ var body = "";
+ enyo.forEach(this._fields, function(field) {
+ body += "--" + boundary + "\r\n";
+ if (field[2] || field[1].name) {
+ // file upload
+ var file = field[1], filename = field[2] || file.name;
+ body += "Content-Disposition: form-data; name=\""+ field[0] +"\"; filename=\""+ filename +"\"\r\n";
+ body += "Content-Type: "+ file.type +"\r\n\r\n";
+ body += file.getAsBinary() + "\r\n";
+ } else {
+ // key-value field
+ body += "Content-Disposition: form-data; name=\""+ field[0] +"\";\r\n\r\n";
+ body += field[1] + "\r\n";
+ }
+ });
+ body += "--" + boundary +"--";
+ return body;
+ };
+ enyo.FormData = FormData;
+
+ function Blob(inBufs, inOpts) {
+ this.name = inOpts.name;
+ this.type = inOpts.type || 'application/octet-stream';
+ if (!enyo.isArray(inBufs)) {
+ throw new Error('enyo.Blob only handles Arrays of Strings');
+ }
+ if ((inBufs.length > 0) && typeof inBufs[0] !== 'string') {
+ throw new Error('enyo.Blob only handles Arrays of Strings');
+ }
+ this._bufs = inBufs; // leave byte arrays un-touched
+ }
+ Blob.prototype.getAsBinary = function() {
+ var empty = '',
+ content = empty.concat.apply(empty, this._bufs);
+ return content;
+ };
+ enyo.Blob = Blob;
+
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceajaxjsonjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ajax/json.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ajax/json.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ajax/json.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+enyo.json = {
+ //* @public
+ /**
+ Returns a JSON string for a given object, using native stringify
+ routine.
+ <i>inValue</i> is the Object to be converted to JSON.
+ <i>inReplacer</i> is the optional value inclusion array or replacement function.
+ <i>inSpace</i> is the optional number or string to use for pretty-printing whitespace.
+ */
+ stringify: function(inValue, inReplacer, inSpace) {
+ return JSON.stringify(inValue, inReplacer, inSpace);
+ },
+ /**
+ Returns a JavaScript object for a given JSON string, using native stringify
+ routine.
+ <i>inJson</i> is the JSON string to be converted to a JavaScript object.
+ */
+ parse: function(inJson, inReviver) {
+ return inJson ? JSON.parse(inJson, inReviver) : null;
+ }
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceajaxpackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ajax/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ajax/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ajax/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+enyo.depends(
+ "Async.js",
+ "json.js",
+ "cookie.js",
+ "xhr.js",
+ "formdata.js",
+ "AjaxProperties.js",
+ "Ajax.js",
+ "Jsonp.js",
+ "WebService.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceajaxxhrjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ajax/xhr.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ajax/xhr.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ajax/xhr.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,143 @@
</span><ins>+//* @protected
+/**
+ If you make changes to _enyo.xhr_, be sure to add or update the appropriate
+ [unit tests](https://github.com/enyojs/enyo/tree/master/tools/test/ajax/tests).
+*/
+enyo.xhr = {
+ /**
+ <code>inParams</code> is an Object that may contain these properties:
+
+ - _url_: The URL to request (required).
+ - _method_: The HTTP method to use for the request. Defaults to GET.
+ - _callback_: Called when request is completed. (Optional)
+ - _body_: Specific contents for the request body for POST method. (Optional)
+ - _headers_: Additional request headers. (Optional). Given headers override the ones that Enyo may set by default (`null` explictly removing the header from the AJAX request).
+ - _username_: The optional user name to use for authentication purposes.
+ - _password_: The optional password to use for authentication purposes.
+ - _xhrFields_: Optional object containing name/value pairs to mix directly into the generated xhr object.
+ - _mimeType_: Optional string to override the MIME-Type.
+ */
+ request: function(inParams) {
+ var xhr = this.getXMLHttpRequest(inParams);
+ var url = enyo.path.rewrite(this.simplifyFileURL(inParams.url));
+ //
+ var method = inParams.method || "GET";
+ var async = !inParams.sync;
+ //
+ if (inParams.username) {
+ xhr.open(method, url, async, inParams.username, inParams.password);
+ } else {
+ xhr.open(method, url, async);
+ }
+ //
+ enyo.mixin(xhr, inParams.xhrFields);
+ // only setup handler when we have a callback
+ if (inParams.callback) {
+ this.makeReadyStateHandler(xhr, inParams.callback);
+ }
+ //
+ inParams.headers = inParams.headers || {};
+ // work around iOS 6 bug where non-GET requests are cached
+ // see http://www.einternals.com/blog/web-development/ios6-0-caching-ajax-post-requests
+ // not sure (yet) wether this will be required for later ios releases
+ if (method !== "GET" && enyo.platform.ios && enyo.platform.ios >= 6) {
+ if (inParams.headers["cache-control"] !== null) {
+ inParams.headers["cache-control"] = inParams.headers['cache-control'] || "no-cache";
+ }
+ }
+ // user-set headers override any platform-default
+ if (xhr.setRequestHeader) {
+ for (var key in inParams.headers) {
+ if (inParams.headers[key]) {
+ xhr.setRequestHeader(key, inParams.headers[key]);
+ }
+ }
+ }
+ //
+ if((typeof xhr.overrideMimeType == "function") && inParams.mimeType) {
+ xhr.overrideMimeType(inParams.mimeType);
+ }
+ //
+ xhr.send(inParams.body || null);
+ if (!async && inParams.callback) {
+ xhr.onreadystatechange(xhr);
+ }
+ return xhr;
+ },
+ //* remove any callbacks that might be set from Enyo code for an existing XHR
+ //* and stop the XHR from completing.
+ cancel: function(inXhr) {
+ if (inXhr.onload) {
+ inXhr.onload = null;
+ }
+ if (inXhr.onreadystatechange) {
+ inXhr.onreadystatechange = null;
+ }
+ if (inXhr.abort) {
+ inXhr.abort();
+ }
+ },
+ //* @protected
+ makeReadyStateHandler: function(inXhr, inCallback) {
+ if (window.XDomainRequest && inXhr instanceof XDomainRequest) {
+ inXhr.onload = function() {
+ var text;
+ if (typeof inXhr.responseText === "string") {
+ text = inXhr.responseText;
+ }
+ inCallback.apply(null, [text, inXhr]);
+ };
+ }
+ inXhr.onreadystatechange = function() {
+ if (inXhr.readyState == 4) {
+ var text;
+ if (typeof inXhr.responseText === "string") {
+ text = inXhr.responseText;
+ }
+ inCallback.apply(null, [text, inXhr]);
+ }
+ };
+ },
+ inOrigin: function(inUrl) {
+ var a = document.createElement("a"), result = false;
+ a.href = inUrl;
+ // protocol is ":" for relative URLs
+ if (a.protocol === ":" ||
+ (a.protocol === window.location.protocol &&
+ a.hostname === window.location.hostname &&
+ a.port === (window.location.port ||
+ (window.location.protocol === "https:" ? "443" : "80")))) {
+ result = true;
+ }
+ return result;
+ },
+ simplifyFileURL: function(inUrl) {
+ var a = document.createElement("a"), result = false;
+ a.href = inUrl;
+ // protocol is ":" for relative URLs
+ if (a.protocol === "file:" ||
+ a.protocol === ":" && window.location.protocol === "file:") {
+ // leave off search and hash parts of the URL
+ return a.protocol + '//' + a.host + a.pathname;
+ } else if (a.protocol === ":" && window.location.protocol === "x-wmapp0:") {
+ // explicitly return absolute URL for Windows Phone 8, as an absolute path is required for local files
+ return window.location.protocol + "//" + window.location.pathname.split('/')[0] + "/" + a.host + a.pathname;
+ } else {
+ return inUrl;
+ }
+ },
+ getXMLHttpRequest: function(inParams) {
+ try {
+ // only use XDomainRequest when it exists, no extra headers were set, and the
+ // target URL maps to a domain other than the document origin.
+ if (enyo.platform.ie < 10 && window.XDomainRequest && !inParams.headers &&
+ !this.inOrigin(inParams.url) && !/^file:\/\//.test(window.location.href)) {
+ return new XDomainRequest();
+ }
+ } catch(e) {}
+ try {
+ return new XMLHttpRequest();
+ } catch(e) {}
+ return null;
+ }
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcebootbootjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/boot/boot.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/boot/boot.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/boot/boot.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,133 @@
</span><ins>+// Used when a certain platform restricts functionality due to security
+enyo.execUnsafeLocalFunction = function(e) {
+ // Querying {MSApp} object - Windows 8
+ if (typeof MSApp === "undefined") {
+ e();
+ }
+ else {
+ MSApp.execUnsafeLocalFunction(e);
+ }
+};
+
+// machine for a loader instance
+enyo.machine = {
+ sheet: function(inPath) {
+ var type = "text/css";
+ var rel = "stylesheet";
+ var isLess = (inPath.slice(-5) == ".less");
+ if (isLess) {
+ if (window.less) {
+ // If client-side less is loaded, insert the less stylesheet
+ type = "text/less";
+ rel = "stylesheet/less";
+ } else {
+ // Otherwise, we expect a css file of the same name to exist
+ inPath = inPath.slice(0, inPath.length-4) + "css";
+ }
+ }
+ var link;
+ if (enyo.runtimeLoading || isLess) {
+ link = document.createElement('link');
+ link.href = inPath;
+ link.media = "screen";
+ link.rel = rel;
+ link.type = type;
+ document.getElementsByTagName('head')[0].appendChild(link);
+ } else {
+ link = function() {
+ document.write('<link href="' + inPath + '" media="screen" rel="' + rel + '" type="' + type + '" />');
+ };
+ enyo.execUnsafeLocalFunction(link);
+ }
+ if (isLess && window.less) {
+ less.sheets.push(link);
+ if (!enyo.loader.finishCallbacks.lessRefresh) {
+ enyo.loader.finishCallbacks.lessRefresh = function() {
+ less.refresh(true);
+ };
+ }
+ }
+ },
+ script: function(inSrc, onLoad, onError) {
+ if (!enyo.runtimeLoading) {
+ document.write('<scri' + 'pt src="' + inSrc + '"' + (onLoad ? ' onload="' + onLoad + '"' : '') + (onError ? ' onerror="' + onError + '"' : '') + '></scri' + 'pt>');
+ } else {
+ var script = document.createElement('script');
+ script.src = inSrc;
+ script.onload = onLoad;
+ script.onerror = onError;
+ document.getElementsByTagName('head')[0].appendChild(script);
+ }
+ },
+ inject: function(inCode) {
+ document.write('<scri' + 'pt type="text/javascript">' + inCode + "</scri" + "pt>");
+ }
+};
+
+// create a dependency processor using our script machine
+enyo.loader = new enyo.loaderFactory(enyo.machine);
+
+// dependency API uses enyo loader
+enyo.depends = function() {
+ var ldr = enyo.loader;
+ if (!ldr.packageFolder) {
+ var tag = enyo.locateScript("package.js");
+ if (tag && tag.path) {
+ ldr.aliasPackage(tag.path);
+ ldr.packageFolder = tag.path + "/";
+ //console.log("detected PACKAGEFOLDER [" + ldr.packageFolder + "]");
+ }
+ }
+ ldr.load.apply(ldr, arguments);
+};
+
+// Runtime loader
+// Usage: enyo.load(depends, [onLoadCallback])
+// where - depends is string or array of string paths to package.js, script, or css to load
+// - doneCallback is fired after file or package loading has completed
+// Only one file/package is loaded at a time; additional calls are queued and loading deferred
+(function() {
+ var enyo = window.enyo;
+ var runtimeLoadQueue = [];
+ enyo.load = function(depends, onLoadCallback) {
+ runtimeLoadQueue.push(arguments);
+ if (!enyo.runtimeLoading) {
+ enyo.runtimeLoading = true;
+ runtimeLoad();
+ }
+ };
+ function runtimeLoad(onLoad) {
+ if (onLoad) {
+ onLoad(); // Run user callback function
+ }
+ if (runtimeLoadQueue.length) {
+ var args = runtimeLoadQueue.shift();
+ var depends = args[0];
+ var dependsArg = enyo.isArray(depends) ? depends : [depends];
+ var onLoadCallback = args[1];
+ enyo.loader.finishCallbacks.runtimeLoader = function() {
+ // Once loader is done loading a package, we chain a call to runtimeLoad(),
+ // which will call the onLoadCallback from the original load call, passing
+ // a reference to the depends argument from the original call for tracking,
+ // followed by kicking off any additionally queued load() calls
+ runtimeLoad(function() {
+ if (onLoadCallback) {
+ onLoadCallback(depends);
+ }
+ });
+ };
+ enyo.loader.packageFolder = "./";
+ // Kick off next queued call to loader
+ enyo.depends.apply(this, dependsArg);
+ } else {
+ enyo.runtimeLoading = false;
+ enyo.loader.packageFolder = "";
+ }
+ }
+})();
+
+// predefined path aliases
+enyo.path.addPaths({
+ enyo: enyo.args.root,
+ lib: "$enyo/../lib"
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcebootenyojs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/boot/enyo.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/boot/enyo.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/boot/enyo.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+(function() {
+ // enyo can use information from the script tag that loads this bootstrap file
+ var thisScript = "enyo.js";
+
+ enyo = window.enyo || {};
+
+ enyo.locateScript = function(inName) {
+ var scripts = document.getElementsByTagName("script");
+ for (var i=scripts.length-1, s, src, l=inName.length; (i>=0) && (s=scripts[i]); i--) {
+ if (!s.located) {
+ src = s.getAttribute("src") || "";
+ if (src.slice(-l) == inName) {
+ s.located = true;
+ return {path: src.slice(0, Math.max(0, src.lastIndexOf("/"))), node: s};
+ }
+ }
+ }
+ };
+
+ enyo.args = enyo.args || {};
+
+ var tag = enyo.locateScript(thisScript);
+ if (tag) {
+ // infer the framework path from the document, unless the user has specified one explicitly
+ enyo.args.root = (enyo.args.root || tag.path).replace("/source", "");
+ // all attributes of the bootstrap script tag become enyo.args
+ for (var i=0, al = tag.node.attributes.length, it; (i < al) && (it = tag.node.attributes.item(i)); i++) {
+ enyo.args[it.nodeName] = it.value;
+ }
+ }
+})();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcebootpackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/boot/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/boot/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/boot/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+enyo.depends(
+ "enyo.js",
+ "../../loader.js",
+ "boot.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedomControljs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/Control.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/Control.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/Control.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,879 @@
</span><ins>+/**
+ _enyo.Control_ is a component that controls a DOM node (i.e., an element in
+ the user interface). Controls are generally visible and the user often
+ interacts with them directly. While things like buttons and input boxes are
+ obviously controls, in Enyo, a control may become as complex as an entire
+ application.
+
+ If you make changes to _enyo.Control_, be sure to add or update the appropriate
+ [unit tests](https://github.com/enyojs/enyo/tree/master/tools/test/core/tests).
+
+ For more information, see the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Creating-Controls">Controls</a>
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.Control",
+ kind: enyo.UiComponent,
+ published: {
+ /**
+ HTML tag name to use for the control. If null, no tag is generated;
+ only the contents are used.
+ */
+ tag: "div",
+ //* Hash of DOM attributes to apply to the generated HTML tag
+ attributes: null,
+ //* Space-delimited set of CSS classes to apply to the generated HTML tag
+ classes: "",
+ //* Style attribute to apply to the generated HTML tag
+ style: "",
+ /**
+ Content that will be generated inside the HTML tag; defaults to
+ plain text unless _allowHtml_ is true
+ */
+ content: "",
+ //* Boolean indicating whether the tag will be visible in the document
+ showing: true,
+ //* If false, HTML codes in _content_ are escaped before rendering
+ allowHtml: false,
+ //
+ // convenience properties for common attributes
+ //
+ //* Shortcut for setting _src_ attribute in _attributes_ hash. Overrides that value.
+ src: "",
+ //
+ // esoteric
+ //
+ /**
+ Set to false if the control should not generate any HTML. Used to
+ inhibit generation of popups until they're shown at runtime.
+ */
+ canGenerate: true,
+ //
+ // ad hoc properties:
+ //
+ /**
+ Flag used by control layouts to determine which control will expand
+ to fill the available space. This only has meaning when the control
+ is being used as a child of a control with a version of FittableLayout
+ as its layoutKind.
+ */
+ fit: false,
+ //* Used by Ares design editor for design objects
+ isContainer: false
+ },
+ handlers: {
+ //* Controls will call a user-provided _tap_ method when tapped upon.
+ ontap: "tap"
+ },
+ //* The default kind for controls created inside this control that don't
+ //* specify their own kind
+ defaultKind: "Control",
+ //* A set of CSS classes that are applied to controls created inside this control
+ controlClasses: "",
+ //* @protected
+ node: null,
+ generated: false,
+ create: function() {
+ // initialize style databases
+ this.initStyles();
+ // superkind initialization
+ this.inherited(arguments);
+ // 'showing' is tertiary method for modifying display style
+ // setting 'display: none;' style at initialization time will
+ // not work if 'showing' is true.
+ this.showingChanged();
+ // Notes:
+ // - 'classes' does not reflect the complete set of classes on an object; the complete set is in
+ // this.attributes.class. The '*Class' apis affect this.attributes.class.
+ // - use addClass instead of setClasses here, by convention 'classes' is reserved for instance objects
+ // - inheritors should 'addClass' to add classes
+ // - setClasses removes the old classes and adds the new one, setClassAttribute replaces all classes
+ this.addClass(this.kindClasses);
+ this.addClass(this.classes);
+ this.initProps(["id", "content", "src"]);
+ },
+ destroy: function() {
+ this.removeNodeFromDom();
+ enyo.Control.unregisterDomEvents(this.id);
+ this.inherited(arguments);
+ },
+ importProps: function(inProps) {
+ this.inherited(arguments);
+ // each instance has its own attributes array, the union of the prototype attributes and user-specified attributes
+ this.attributes = enyo.mixin(enyo.clone(this.kindAttributes), this.attributes);
+ },
+ initProps: function(inPropNames) {
+ // for each named property, trigger the *Changed handler if the property value is truthy
+ for (var i=0, n, cf; (n=inPropNames[i]); i++) {
+ if (this[n]) {
+ // FIXME: awkward
+ cf = n + "Changed";
+ if (this[cf]) {
+ this[cf]();
+ }
+ }
+ }
+ },
+ classesChanged: function(inOld) {
+ this.removeClass(inOld);
+ this.addClass(this.classes);
+ },
+ // modify components we create ourselves
+ /*
+ adjustComponentProps: function(inProps) {
+ if (this.controlClasses) {
+ inProps.classes = (inProps.classes ? inProps.classes + " " : "") + this.controlClasses;
+ }
+ this.inherited(arguments);
+ },
+ */
+ addChild: function(inControl) {
+ inControl.addClass(this.controlClasses);
+ this.inherited(arguments);
+ },
+ removeChild: function(inControl) {
+ this.inherited(arguments);
+ inControl.removeClass(this.controlClasses);
+ },
+ // event filter
+ strictlyInternalEvents: {onenter: 1, onleave: 1},
+ dispatchEvent: function(inEventName, inEvent, inSender) {
+ // prevent dispatch and bubble of events that are strictly internal (e.g. enter/leave)
+ if (this.strictlyInternalEvents[inEventName] && this.isInternalEvent(inEvent)) {
+ return true;
+ }
+ return this.inherited(arguments);
+ },
+ isInternalEvent: function(inEvent) {
+ var rdt = enyo.dispatcher.findDispatchTarget(inEvent.relatedTarget);
+ return rdt && rdt.isDescendantOf(this);
+ },
+ //
+ //* @public
+ /**
+ Returns the DOM node representing the control.
+ If the control is not currently rendered, returns null.
+
+ If hasNode() returns a value, the _node_ property will be valid and
+ can be checked directly.
+
+ Once hasNode() is called, the returned value is made available in
+ the _node_ property of this control.
+
+ A control will only return a node if it has been rendered.
+
+ if (this.hasNode()) {
+ enyo.log(this.node.nodeType);
+ }
+ */
+ hasNode: function() {
+ // 'generated' is used to gate access to expensive findNodeById call
+ return this.generated && (this.node || this.findNodeById());
+ },
+ /**
+ Appends the string value of _inAddendum_ to the _content_ of this
+ control.
+ */
+ addContent: function(inAddendum) {
+ this.setContent(this.content + inAddendum);
+ },
+ /**
+ Gets the value of an attribute on this object.
+
+ If this control has a node, the attribute value is retrieved from the
+ node; otherwise, it's read from the _attributes_ property of the control
+ itself.
+
+ Caveat: If the control is rendered, the _attributes_ property is used to
+ construct the rendering, and values that have changed on the node itself
+ are lost.
+
+ // Get the value attribute for this DomNode
+ var value = this.getAttribute("tabIndex");
+ */
+ getAttribute: function(inName) {
+ return this.hasNode() ? this.node.getAttribute(inName) : this.attributes[inName];
+ },
+ /**
+ Sets the value of an attribute on this object. Pass null _inValue_ to
+ remove an attribute.
+
+ // set the tabIndex attribute for this DomNode
+ this.setAttribute("tabIndex", 3);
+ ...
+ // remove the index attribute
+ this.setAttribute("index", null);
+ */
+ setAttribute: function(inName, inValue) {
+ this.attributes[inName] = inValue;
+ if (this.hasNode()) {
+ this.attributeToNode(inName, inValue);
+ }
+ this.invalidateTags();
+ },
+ /**
+ Gets the value of a property named _inName_ directly from the DOM node.
+ A caller-specified default value, _inDefault_, is returned when the DOM
+ node has not yet been created.
+ */
+ getNodeProperty: function(inName, inDefault) {
+ if (this.hasNode()) {
+ return this.node[inName];
+ } else {
+ return inDefault;
+ }
+ },
+ /**
+ Sets the value of the _inName_ property on the control's DOM node to
+ _inValue_, if and only if the DOM node has been rendered. This method
+ does not alter any values cached in local properties of the
+ _enyo.Control_ instance.
+ */
+ setNodeProperty: function(inName, inValue) {
+ if (this.hasNode()) {
+ this.node[inName] = inValue;
+ }
+ },
+ /**
+ Convenience function for setting the _class_ attribute.
+ The _class_ attribute represents the CSS classes assigned to this object;
+ it is a string that can contain multiple CSS classes separated by spaces.
+
+ this.$.control.setClassAttribute("box blue-border highlighted");
+ */
+ setClassAttribute: function(inClass) {
+ this.setAttribute("class", inClass);
+ },
+ /**
+ Convenience function for getting the _class_ attribute.
+ The _class_ attribute represents the CSS classes assigned to this object;
+ it is a string that can contain multiple CSS classes separated by spaces.
+
+ var cssClasses = this.$.control.getClassAttribute();
+ */
+ getClassAttribute: function() {
+ return this.attributes["class"] || "";
+ },
+ /**
+ Returns true if the _class_ attribute contains a substring matching
+ _inClass_.
+
+ The _class_ attribute is a string that can contain multiple CSS classes.
+ This method tests whether a particular class is part of the set of
+ classes on this control.
+
+ // returns true if _class_ is "bar foo baz", but false for "barfoobaz"
+ var hasFooClass = this.$.control.hasClass("foo");
+ */
+ hasClass: function(inClass) {
+ return inClass && ((" " + this.getClassAttribute() + " ").indexOf(" " + inClass + " ") >= 0);
+ },
+ /**
+ Adds CSS class name _inClass_ to the _class_ attribute of this object.
+
+ // add the highlight class to this object
+ this.addClass("highlight");
+ */
+ addClass: function(inClass) {
+ if (inClass && !this.hasClass(inClass)) {
+ var c = this.getClassAttribute();
+ this.setClassAttribute(c + (c ? " " : "") + inClass);
+ }
+ },
+ /**
+ Removes substring _inClass_ from the _class_ attribute of this object.
+
+ _inClass_ must have no leading or trailing spaces.
+
+ Using a compound class name is supported, but the name is treated
+ atomically. For example, given _"a b c"_, _removeClass("a b")_ will
+ produce _"c"_, but _removeClass("a c")_ will produce _"a b c"_.
+
+ // remove the highlight class from this object
+ this.removeClass("highlight");
+ */
+ removeClass: function(inClass) {
+ if (inClass && this.hasClass(inClass)) {
+ var c = this.getClassAttribute();
+ c = (" " + c + " ").replace(" " + inClass + " ", " ").slice(1, -1);
+ this.setClassAttribute(c);
+ }
+ },
+ /**
+ Adds or removes substring _inClass_ from the _class_ attribute of this
+ object based on the value of _inTrueToAdd_.
+
+ If _inTrueToAdd_ is truthy, then _inClass_ is added; otherwise,
+ _inClass_ is removed.
+
+ // add or remove the highlight class, depending on the "highlighted" property
+ this.addRemoveClass("highlight", this.highlighted);
+ */
+ addRemoveClass: function(inClass, inTrueToAdd) {
+ this[inTrueToAdd ? "addClass" : "removeClass"](inClass);
+ },
+ //
+ // styles
+ //
+ //* @protected
+ initStyles: function() {
+ this.domStyles = this.domStyles || {};
+ enyo.Control.cssTextToDomStyles(this.kindStyle, this.domStyles);
+ this.domCssText = enyo.Control.domStylesToCssText(this.domStyles);
+ },
+ styleChanged: function() {
+ // FIXME: stomping on domStyles is problematic, there may be styles on this object
+ // applied by layouts or other objects.
+ // We may need a 'runtimeStyles' concept separate from a 'userStyles' concept, although
+ // it's not clear what API calls like 'applyStyle' would affect, and which concept would take
+ // precedence when there is a conflict.
+ // Perhaps we can separate 'style' completely from 'domStyles'. API methods like applyStyle
+ // would affect domStyles, and the two style databases would be combined at render-time.
+ // Alternatively, we can disallow changing "style" string at runtime and allow it to be set
+ // at init-time only (as it was in pre-ares enyo).
+ //this.domStyles = {};
+ //this.addStyles(this.kindStyle);
+ //this.addStyles(this.style);
+ this.invalidateTags();
+ this.renderStyles();
+ },
+ //* @public
+ /**
+ Applies a single style value to this object.
+
+ this.$.box.applyStyle("z-index", 4);
+
+ You may remove a style by setting its value to null.
+
+ this.$.box.applyStyle("z-index", null);
+ */
+ applyStyle: function(inStyle, inValue) {
+ this.domStyles[inStyle] = inValue;
+ this.domStylesChanged();
+ },
+ /**
+ Adds CSS styles to the set of styles assigned to this object.
+
+ _inCssText_ is a string containing CSS styles in text format.
+
+ this.$.box.addStyles("background-color: red; padding: 4px;");
+ */
+ addStyles: function(inCssText) {
+ enyo.Control.cssTextToDomStyles(inCssText, this.domStyles);
+ this.domStylesChanged();
+ },
+ /**
+ Returns the computed value of a CSS style named from _inStyle_
+ for the DOM node of the control. If the node hasn't been generated,
+ returns _inDefault_ as a default value. This uses JavaScript-style
+ property names, not CSS-style names, so use "fontFamily" instead of
+ "font-family".
+ */
+ getComputedStyleValue: function(inStyle, inDefault) {
+ if (this.hasNode()) {
+ return enyo.dom.getComputedStyleValue(this.node, inStyle);
+ }
+ return inDefault;
+ },
+ //* @protected
+ domStylesChanged: function() {
+ this.domCssText = enyo.Control.domStylesToCssText(this.domStyles);
+ this.invalidateTags();
+ this.renderStyles();
+ },
+ stylesToNode: function() {
+ this.node.style.cssText = this.style + (this.style[this.style.length-1] == ';' ? ' ' : '; ') + this.domCssText;
+ },
+ setupBodyFitting: function() {
+ enyo.dom.applyBodyFit();
+ this.addClass("enyo-fit enyo-clip");
+ },
+ /*
+ If the platform is Android or Android-Chrome, don't include
+ the css rule -webkit-overflow-scrolling: touch, as it is
+ not supported in Android and leads to overflow issues
+ (ENYO-900 and ENYO-901)
+ Similarly, BB10 has issues repainting out-of-viewport content
+ when -webkit-overflow-scrolling is used (ENYO-1396)
+ */
+ setupOverflowScrolling: function() {
+ if(enyo.platform.android || enyo.platform.androidChrome || enyo.platform.blackberry)
+ return;
+ document.getElementsByTagName("body")[0].className += " webkitOverflowScrolling";
+ },
+ //
+ //
+ //* @public
+ /**
+ Renders this object into DOM, generating a DOM node if needed.
+ */
+ render: function() {
+ if (this.parent) {
+ // allow the parent to perform setup tasks
+ // note: ('parent.generated' may change here)
+ this.parent.beforeChildRender(this);
+ // don't render if the parent has not generated
+ if (!this.parent.generated) {
+ return this;
+ }
+ }
+ if (!this.hasNode()) {
+ this.renderNode();
+ }
+ if (this.hasNode()) {
+ this.renderDom();
+ if (this.generated) {
+ this.rendered();
+ }
+ }
+ // return 'this' to support method chaining
+ return this;
+ },
+ /**
+ Renders this object into the DOM node referenced by _inParentNode_.
+ If rendering into the document body element, appropriate styles will
+ be used to have it expand to fill the whole window.
+ */
+ renderInto: function(inParentNode) {
+ // clean up render flags and memoizations
+ this.teardownRender();
+ // inParentNode can be a string id or a node reference
+ var pn = enyo.dom.byId(inParentNode);
+ if (pn == document.body) {
+ this.setupBodyFitting();
+ } else if (this.fit) {
+ this.addClass("enyo-fit enyo-clip");
+ }
+ // for IE10 support, we want full support over touch actions in Enyo-rendered areas
+ this.addClass("enyo-no-touch-action");
+ // add css to enable hw-accelerated scrolling on non-Android platforms (ENYO-900, ENYO-901)
+ this.setupOverflowScrolling();
+ // generate our HTML
+ enyo.dom.setInnerHtml(pn, this.generateHtml());
+ // post-rendering tasks
+ if (this.generated) {
+ this.rendered();
+ }
+ // support method chaining
+ return this;
+ },
+ /**
+ Uses _document.write_ to output the control into the document.
+ If the control has _fit: true_ defined, appropriate styles will be set
+ to have it expand to fill its container.
+
+ Note that this has all the limitations that _document.write_ has.
+ It only works while the page is loading, so you can't call this from an
+ event handler. Also, it will not work in certain environments, such as
+ Chrome Packaged Apps or Windows 8.
+ */
+ write: function() {
+ if (this.fit) {
+ this.setupBodyFitting();
+ }
+ // for IE10 support, we want full support over touch actions in Enyo-rendered areas
+ this.addClass("enyo-no-touch-action");
+ // add css to enable hw-accelerated scrolling on non-Android platforms (ENYO-900, ENYO-901)
+ this.setupOverflowScrolling();
+ document.write(this.generateHtml());
+ // post-rendering tasks
+ if (this.generated) {
+ this.rendered();
+ }
+ // support method chaining
+ return this;
+ },
+ /**
+ Override this method to perform tasks that require access to the DOM node.
+
+ rendered: function() {
+ this.inherited(arguments);
+ // do some task
+ }
+ */
+ rendered: function() {
+ // CAVEAT: Currently we use one entry point ('reflow') for
+ // post-render layout work *and* post-resize layout work.
+ this.reflow();
+ for (var i=0, c; (c=this.children[i]); i++) {
+ if (c.generated) {
+ c.rendered();
+ }
+ }
+ },
+ /**
+ Shows this node (alias for _setShowing(true)_).
+ */
+ show: function() {
+ this.setShowing(true);
+ },
+ /**
+ Hides this node (alias for _setShowing(false)_).
+ */
+ hide: function() {
+ this.setShowing(false);
+ },
+ /**
+ Returns an object describing the geometry of this object, like so:
+
+ {left: _offsetLeft_, top: _offsetTop_, width: _offsetWidth_, height: _offsetHeight_}
+
+ Values returned are only valid if _hasNode()_ is truthy.
+ If there's no DOM node for the object, this returns a bounds structure with
+ _undefined_ as the value of all fields.
+
+ var bounds = this.getBounds();
+ enyo.log(bounds.width);
+ */
+ getBounds: function() {
+ var n = this.node || this.hasNode();
+ var b = enyo.dom.getBounds(n);
+ return b || {left: undefined, top: undefined, width: undefined, height: undefined};
+ },
+ /**
+ Sets any or all of the geometry style properties _width_, _height_,
+ _left_, _top_, _right_ and _bottom_.
+
+ Values may be specified as strings (with units included), or as numbers
+ when a unit is provided in _inUnit_.
+
+ this.setBounds({width: 100, height: 100}, "px"); // adds style properties like "width: 100px; height: 100px;"
+ //
+ this.setBounds({width: "10em", right: "30pt"}); // adds style properties like "width: 10em; right: 30pt;"
+ */
+ setBounds: function(inBounds, inUnit) {
+ var s = this.domStyles, unit = inUnit || "px";
+ var extents = ["width", "height", "left", "top", "right", "bottom"];
+ for (var i=0, b, e; (e=extents[i]); i++) {
+ b = inBounds[e];
+ if (b || b === 0) {
+ s[e] = b + (!enyo.isString(b) ? unit : '');
+ }
+ }
+ this.domStylesChanged();
+ },
+ //* @protected
+ // expensive, other methods do work to avoid calling here
+ findNodeById: function() {
+ return this.id && (this.node = enyo.dom.byId(this.id));
+ },
+ idChanged: function(inOld) {
+ if (inOld) {
+ enyo.Control.unregisterDomEvents(inOld);
+ }
+ this.setAttribute("id", this.id);
+ if (this.id) {
+ enyo.Control.registerDomEvents(this.id, this);
+ }
+ },
+ contentChanged: function() {
+ if (this.hasNode()) {
+ this.renderContent();
+ }
+ },
+ getSrc: function() {
+ return this.getAttribute("src");
+ },
+ srcChanged: function() {
+ this.setAttribute("src", enyo.path.rewrite(this.src));
+ },
+ attributesChanged: function() {
+ this.invalidateTags();
+ this.renderAttributes();
+ },
+ //
+ // HTML rendering
+ //
+ generateHtml: function() {
+ if (this.canGenerate === false) {
+ return '';
+ }
+ // do this first in case content generation affects outer html (styles or attributes)
+ var c = this.generateInnerHtml();
+ // generate tag, styles, attributes
+ var h = this.generateOuterHtml(c);
+ // NOTE: 'generated' is used to gate access to findNodeById in
+ // hasNode, because findNodeById is expensive.
+ // NOTE: we typically use 'generated' to mean 'created in DOM'
+ // but that has not actually happened at this point.
+ // We set 'generated = true' here anyway to avoid having to walk the
+ // control tree a second time (to set it later).
+ // The contract is that insertion in DOM will happen synchronously
+ // to generateHtml() and before anybody should be calling hasNode().
+ this.generated = true;
+ return h;
+ },
+ generateInnerHtml: function() {
+ // Flow can alter the way that html content is rendered inside
+ // the container regardless of whether there are children.
+ this.flow();
+ if (this.children.length) {
+ return this.generateChildHtml();
+ } else {
+ return this.allowHtml ? this.content : enyo.Control.escapeHtml(this.content);
+ }
+ },
+ generateChildHtml: function() {
+ var results = '';
+ for (var i=0, c; (c=this.children[i]); i++) {
+ var h = c.generateHtml();
+ results += h;
+ }
+ return results;
+ },
+ generateOuterHtml: function(inContent) {
+ if (!this.tag) {
+ return inContent;
+ }
+ if (!this.tagsValid) {
+ this.prepareTags();
+ }
+ return this._openTag + inContent + this._closeTag;
+ },
+ invalidateTags: function() {
+ this.tagsValid = false;
+ },
+ prepareTags: function() {
+ var htmlStyle = this.domCssText + this.style;
+ this._openTag = '<' +
+ this.tag +
+ (htmlStyle ? ' style="' + htmlStyle + '"' : "") +
+ enyo.Control.attributesToHtml(this.attributes);
+ if (enyo.Control.selfClosing[this.tag]) {
+ this._openTag += '/>';
+ this._closeTag = '';
+ } else {
+ this._openTag += '>';
+ this._closeTag = '</' + this.tag + '>';
+ }
+ this.tagsValid = true;
+ },
+ // DOM, aka direct-to-node, rendering
+ attributeToNode: function(inName, inValue) {
+ if (inValue === null || inValue === false || inValue === "") {
+ this.node.removeAttribute(inName);
+ } else {
+ this.node.setAttribute(inName, inValue);
+ }
+ },
+ attributesToNode: function() {
+ for (var n in this.attributes) {
+ this.attributeToNode(n, this.attributes[n]);
+ }
+ },
+ getParentNode: function() {
+ return this.parentNode || (this.parent && (this.parent.hasNode() || this.parent.getParentNode()));
+ },
+ addNodeToParent: function() {
+ if (this.node) {
+ var pn = this.getParentNode();
+ if (pn) {
+ if (this.addBefore !== undefined) {
+ this.insertNodeInParent(pn, this.addBefore && this.addBefore.hasNode());
+ } else {
+ this.appendNodeToParent(pn);
+ }
+ }
+ }
+ },
+ appendNodeToParent: function(inParentNode) {
+ inParentNode.appendChild(this.node);
+ },
+ insertNodeInParent: function(inParentNode, inBeforeNode) {
+ inParentNode.insertBefore(this.node, inBeforeNode || inParentNode.firstChild);
+ },
+ removeNodeFromDom: function() {
+ if (this.hasNode() && this.node.parentNode) {
+ this.node.parentNode.removeChild(this.node);
+ }
+ },
+ teardownRender: function() {
+ if (this.generated) {
+ this.teardownChildren();
+ }
+ this.node = null;
+ this.generated = false;
+ },
+ teardownChildren: function() {
+ for (var i=0, c; (c=this.children[i]); i++) {
+ c.teardownRender();
+ }
+ },
+ renderNode: function() {
+ this.teardownRender();
+ this.node = document.createElement(this.tag);
+ this.addNodeToParent();
+ this.generated = true;
+ },
+ renderDom: function() {
+ this.renderAttributes();
+ this.renderStyles();
+ this.renderContent();
+ },
+ renderContent: function() {
+ if (this.generated) {
+ this.teardownChildren();
+ }
+ enyo.dom.setInnerHtml(this.node, this.generateInnerHtml());
+ },
+ renderStyles: function() {
+ if (this.hasNode()) {
+ this.stylesToNode();
+ }
+ },
+ renderAttributes: function() {
+ if (this.hasNode()) {
+ this.attributesToNode();
+ }
+ },
+ beforeChildRender: function() {
+ // if we are generated, we should flow before rendering a child
+ // if not, the render context isn't ready anyway
+ if (this.generated) {
+ this.flow();
+ }
+ },
+ syncDisplayToShowing: function() {
+ var ds = this.domStyles;
+ if (this.showing) {
+ // note: only show a node if it's actually hidden
+ // this way we prevent overriding the value of domStyles.display
+ if (ds.display == "none") {
+ this.applyStyle("display", this._displayStyle || "");
+ }
+ } else {
+ // cache the previous showing value of display
+ // note: we could use a class to hide a node, but then
+ // hide would not override a setting of display: none in style,
+ // which seems bad.
+ this._displayStyle = (ds.display == "none" ? "" : ds.display);
+ this.applyStyle("display", "none");
+ }
+ },
+ showingChanged: function() {
+ this.syncDisplayToShowing();
+ },
+ getShowing: function() {
+ // 'showing' specifically means domStyles.display !== 'none'.
+ // 'showing' does not imply the node is actually visible or even rendered in DOM,
+ // it simply reflects this state of this specific property as a convenience.
+ return this.showing = (this.domStyles.display != "none");
+ },
+ //
+ //
+ fitChanged: function(inOld) {
+ this.parent.reflow();
+ },
+ //
+ //
+ statics: {
+ /**
+ Returns passed-in string with ampersand, less-than, and greater-than
+ characters replaced by HTML entities, e.g.,
+ '<code>"This & That"</code>' becomes
+ '&lt;code&gt;"This &amp; That"&lt;/code&gt;'
+ */
+ escapeHtml: function(inText) {
+ return inText != null ? String(inText).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>') : '';
+ },
+ //* @protected
+ registerDomEvents: function(inId, inControl) {
+ enyo.$[inId] = inControl;
+ },
+ unregisterDomEvents: function(inId) {
+ enyo.$[inId] = null;
+ },
+ selfClosing: {img: 1, hr: 1, br: 1, area: 1, base: 1, basefont: 1, input: 1, link: 1, meta: 1,
+ command: 1, embed: 1, keygen: 1, wbr: 1, param: 1, source: 1, track: 1, col: 1},
+ cssTextToDomStyles: function(inText, inStyleHash) {
+ if (inText) {
+ // remove spaces between rules, then split rules on delimiter (;)
+ var rules = inText.replace(/; /g, ";").split(";");
+ // parse string styles into name/value pairs
+ for (var i=0, s, n, v, rule; (rule=rules[i]); i++) {
+ // "background-image: url(http://foo.com/foo.png)" => ["background-image", "url(http", "//foo.com/foo.png)"]
+ s = rule.split(":");
+ // n = "background-image", s = ["url(http", "//foo.com/foo.png)"]
+ n = s.shift();
+ // v = ["url(http", "//foo.com/foo.png)"].join(':') = "url(http://foo.com/foo.png)"
+ v = s.join(':');
+ // store name/value pair
+ inStyleHash[n] = v;
+ }
+ }
+ },
+ domStylesToCssText: function(inStyleHash) {
+ var n, v, text = '';
+ for (n in inStyleHash) {
+ v = inStyleHash[n];
+ if ((v !== null) && (v !== undefined) && (v !== "")) {
+ text += n + ':' + v + ';';
+ }
+ }
+ return text;
+ },
+ stylesToHtml: function(inStyleHash) {
+ var cssText = enyo.Control.domStylesToCssText(inStyleHash);
+ return (cssText ? ' style="' + cssText + '"' : "");
+ },
+ /**
+ Returns passed-in string with ampersand and double quote characters
+ replaced by HTML entities, e.g., 'hello from "Me & She"' becomes
+ 'hello from &quot;Me &amp; She&quot;'
+ */
+ escapeAttribute: function(inText) {
+ return !enyo.isString(inText) ? inText : String(inText).replace(/&/g,'&').replace(/\"/g,'"');
+ },
+ attributesToHtml: function(inAttributeHash) {
+ var n, v, h = '';
+ for (n in inAttributeHash) {
+ v = inAttributeHash[n];
+ if (v !== null && v !== false && v !== "") {
+ h += ' ' + n + '="' + enyo.Control.escapeAttribute(v) + '"';
+ }
+ }
+ return h;
+ }
+ }
+});
+
+enyo.defaultCtor = enyo.Control;
+
+enyo.Control.subclass = function(ctor, props) {
+ // Control classes may declare properties that are intended
+ // to stack with superclass properties.
+ //
+ // We resort to prototype magic to assemble these properties
+ // at kind declaration time, in the interest of efficiency
+ // and ease of use.
+ //
+ // However, the properties are no longer 'live' in prototypes
+ // because of this magic--i.e., changes to the prototype of
+ // a Control subclass will not necessarily be reflected in
+ // instances of that control (e.g., chained prototypes).
+ //
+ // These properties are also renamed to kind* to allow
+ // combining with instance properties.
+ //
+ var proto = ctor.prototype;
+ //
+ // 'kindClasses' comes either from our inheritance chain (e.g., proto's prototype chain)
+ // or has been forced by a kind declaration.
+ //
+ if (proto.classes) {
+ var kc = proto.kindClasses;
+ proto.kindClasses = (kc ? kc + " " : "") + proto.classes;
+ proto.classes = "";
+ }
+ if (proto.style) {
+ var ks = proto.kindStyle;
+ proto.kindStyle = (ks ? ks + ";" : "") + proto.style;
+ proto.style = "";
+ }
+ if (props.attributes) {
+ var ka = proto.kindAttributes;
+ proto.kindAttributes = enyo.mixin(enyo.clone(ka), proto.attributes);
+ proto.attributes = null;
+ }
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedomanimationjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/animation.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/animation.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/animation.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,99 @@
</span><ins>+(function() {
+ var ms = Math.round(1000/60);
+ var prefix = ["webkit", "moz", "ms", "o", ""];
+ var r = "requestAnimationFrame";
+ var c = "cancel" + enyo.cap(r);
+ // fallback on setTimeout and clearTimeout
+ var _requestFrame = function(inCallback) {
+ return window.setTimeout(inCallback, ms);
+ };
+ var _cancelFrame = function(inId) {
+ return window.clearTimeout(inId);
+ };
+ for (var i = 0, pl = prefix.length, p, wc, wr; (p = prefix[i]) || i < pl; i++) {
+ // if we're on ios 6 just use setTimeout, requestAnimationFrame has some kinks currently
+ if (enyo.platform.ios >= 6) {
+ break;
+ }
+
+ // if prefixed, becomes Request and Cancel
+ wc = p ? (p + enyo.cap(c)) : c;
+ wr = p ? (p + enyo.cap(r)) : r;
+ // Test for cancelRequestAnimationFrame, because some browsers (Firefix 4-10) have a request without a cancel
+ if (window[wc]) {
+ _cancelFrame = window[wc];
+ _requestFrame = window[wr];
+ if (p == "webkit") {
+ /*
+ Note: In Chrome, the first return value of webkitRequestAnimationFrame is 0.
+ We make 1 bogus call so the first used return value of webkitRequestAnimationFrame is > 0, as the spec requires.
+ This makes it so that the requestId is always truthy.
+ (we choose to do this rather than wrapping the native function to avoid the overhead)
+ */
+ _cancelFrame(_requestFrame(enyo.nop));
+ }
+ break;
+ }
+ }
+ /**
+ Requests an animation callback.
+
+ On compatible browsers, if _inNode_ is defined, the callback will fire only if _inNode_ is visible.
+
+ Returns a request id to be used with [enyo.cancelRequestAnimationFrame](#enyo.cancelRequestAnimationFrame).
+ */
+ enyo.requestAnimationFrame = function(inCallback, inNode) {
+ return _requestFrame(inCallback, inNode);
+ };
+ /**
+ Cancels a requested animation callback with the specified id.
+ */
+ enyo.cancelRequestAnimationFrame = function(inId) {
+ return _cancelFrame(inId);
+ };
+})();
+
+/**
+ An assortment of interpolation functions for animations.
+
+ Similar in function to CSS3 transitions.
+
+ Intended for use with [enyo.easedLerp](#enyo.easedLerp)
+*/
+enyo.easing = {
+ cubicIn: function(n) {
+ return Math.pow(n, 3);
+ },
+ cubicOut: function(n) {
+ return Math.pow(n - 1, 3) + 1;
+ },
+ expoOut: function(n) {
+ return (n == 1) ? 1 : (-1 * Math.pow(2, -10 * n) + 1);
+ },
+ quadInOut: function(n){
+ n = n * 2;
+ if (n < 1) {
+ return Math.pow(n, 2) / 2;
+ }
+ return -1 * ((--n) * (n - 2) - 1) / 2;
+ },
+ linear: function(n) {
+ return n;
+ }
+};
+
+/**
+ Gives an interpolation of an animated transition's distance from 0 to 1.
+
+ Given a start time (_inT0_) and an animation duration (_inDuration_), applies
+ the _inEasing_ function to the percentage of time elapsed / duration, capped
+ at 100%.
+*/
+enyo.easedLerp = function(inT0, inDuration, inEasing, reverse) {
+ var lerp = (enyo.now() - inT0) / inDuration;
+ if (reverse) {
+ return lerp >= 1 ? 0 : (1 - inEasing(1 - lerp));
+ } else {
+ return lerp >= 1 ? 1 : inEasing(lerp);
+ }
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedomdispatcherjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/dispatcher.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/dispatcher.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/dispatcher.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,177 @@
</span><ins>+//* @protected
+enyo.$ = {};
+
+enyo.dispatcher = {
+ // these events come from document
+ events: ["mousedown", "mouseup", "mouseover", "mouseout", "mousemove", "mousewheel",
+ "click", "dblclick", "change", "keydown", "keyup", "keypress", "input"],
+ // these events come from window
+ windowEvents: ["resize", "load", "unload", "message"],
+ // these events come from css
+ cssEvents: ["webkitTransitionEnd", "transitionend"],
+ // feature plugins (aka filters)
+ features: [],
+ connect: function() {
+ var d = enyo.dispatcher, i, n;
+ for (i=0; (n=d.events[i]); i++) {
+ d.listen(document, n);
+ }
+ for (i=0; (n=d.cssEvents[i]); i++) {
+ d.listen(document, n);
+ }
+ for (i=0; (n=d.windowEvents[i]); i++) {
+ // Chrome Packaged Apps don't like "unload"
+ if(n === "unload" &&
+ (typeof window.chrome === "object") &&
+ window.chrome.app) {
+ continue;
+ }
+
+ d.listen(window, n);
+ }
+ for (i=0; (n=d.cssEvents[i]); i++) {
+ d.listen(document, n);
+ }
+ },
+ listen: function(inListener, inEventName, inHandler) {
+ var d = enyo.dispatch;
+ if (inListener.addEventListener) {
+ this.listen = function(inListener, inEventName, inHandler) {
+ inListener.addEventListener(inEventName, inHandler || d, false);
+ };
+ } else {
+ //enyo.log("IE8 COMPAT: using 'attachEvent'");
+ this.listen = function(inListener, inEvent, inHandler) {
+ inListener.attachEvent("on" + inEvent, function(e) {
+ e.target = e.srcElement;
+ if (!e.preventDefault) {
+ e.preventDefault = enyo.iePreventDefault;
+ }
+ return (inHandler || d)(e);
+ });
+ };
+ }
+ this.listen(inListener, inEventName, inHandler);
+ },
+ //* Fires an event for Enyo to listen for.
+ dispatch: function(e) {
+ // Find the control who maps to e.target, or the first control that maps to an ancestor of e.target.
+ var c = this.findDispatchTarget(e.target) || this.findDefaultTarget(e);
+ // Cache the original target
+ e.dispatchTarget = c;
+ // support pluggable features return true to abort immediately or set e.preventDispatch to avoid processing.
+ for (var i=0, fn; (fn=this.features[i]); i++) {
+ if (fn.call(this, e) === true) {
+ return;
+ }
+ }
+ if (c && !e.preventDispatch) {
+ this.dispatchBubble(e, c);
+ }
+ },
+ //* Takes an Event.target and finds the corresponding Enyo control.
+ findDispatchTarget: function(inNode) {
+ var t, n = inNode;
+ // FIXME: Mozilla: try/catch is here to squelch "Permission denied to access property xxx from a non-chrome context"
+ // which appears to happen for scrollbar nodes in particular. It's unclear why those nodes are valid targets if
+ // it is illegal to interrogate them. Would like to trap the bad nodes explicitly rather than using an exception block.
+ try {
+ while (n) {
+ if ((t = enyo.$[n.id])) {
+ // there could be multiple nodes with this id, the relevant node for this event is n
+ // we don't push this directly to t.node because sometimes we are just asking what
+ // the target 'would be' (aka, calling findDispatchTarget from handleMouseOverOut)
+ t.eventNode = n;
+ break;
+ }
+ n = n.parentNode;
+ }
+ } catch(x) {
+ enyo.log(x, n);
+ }
+ return t;
+ },
+ //* Returns the default Enyo control for events.
+ findDefaultTarget: function(e) {
+ return enyo.master;
+ },
+ dispatchBubble: function(e, c) {
+ return c.bubble("on" + e.type, e, c);
+ }
+};
+
+// called in the context of an event
+enyo.iePreventDefault = function() {
+ try {
+ this.returnValue = false;
+ }
+ catch(e) {
+ // do nothing
+ }
+};
+
+enyo.dispatch = function(inEvent) {
+ return enyo.dispatcher.dispatch(inEvent);
+};
+
+enyo.bubble = function(inEvent) {
+ // '|| window.event' clause needed for IE8
+ var e = inEvent || window.event;
+ if (e) {
+ // We depend on e.target existing for event tracking and dispatching.
+ if (!e.target) {
+ e.target = e.srcElement;
+ }
+ enyo.dispatch(e);
+ }
+};
+
+// This string is set on event handlers attributes for DOM elements that
+// don't normally bubble (like onscroll) so that they can participate in the
+// Enyo event system.
+enyo.bubbler = "enyo.bubble(arguments[0])";
+
+// The code below helps make Enyo compatible with Google Packages Apps
+// Content Security Policy(http://developer.chrome.com/extensions/contentSecurityPolicy.html)
+// which, among other things forbids use of inline scripts.
+// We replace online scripting with equivalent means, leaving enyo.bubbler
+// for backward compatibility.
+(function() {
+ var bubbleUp = function() {
+ enyo.bubble(arguments[0]);
+ };
+
+ /**
+ * Makes given events bubble on specified enyo contol
+ */
+ enyo.makeBubble = function() {
+ var args = Array.prototype.slice.call(arguments, 0),
+ control = args.shift();
+
+ if((typeof control === "object") && (typeof control.hasNode === "function")) {
+ enyo.forEach(args, function(event) {
+ if(this.hasNode()) {
+ enyo.dispatcher.listen(this.node, event, bubbleUp);
+ }
+ }, control);
+ }
+ };
+})();
+
+// FIXME: we need to create and initialize dispatcher someplace else to allow overrides
+enyo.requiresWindow(enyo.dispatcher.connect);
+
+// generate a tapped event for a raw-click event
+enyo.dispatcher.features.push(
+ function (e) {
+ if ("click" === e.type) {
+ if (e.clientX === 0 && e.clientY === 0) {
+ // this allows the click to dispatch as well
+ // but note the tap event will fire first
+ var cp = enyo.clone(e);
+ cp.type = "tap";
+ enyo.dispatch(cp);
+ }
+ }
+ }
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedomdomcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/dom.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/dom.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/dom.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,100 @@
</span><ins>+/* things we always want */
+body {
+ font-family: 'Helvetica Neue', 'Nimbus Sans L', Arial, sans-serif;
+}
+
+/* allow hw-accelerated scrolling on platforms that support it */
+body.webkitOverflowScrolling {
+ -webkit-overflow-scrolling: touch;
+}
+
+/* for apps */
+.enyo-document-fit {
+ margin: 0;
+ height: 100%;
+ /* note: giving html overflow: auto is odd and was only ever done to avoid duplication
+ however, android 4.04 sometimes does not hide nodes when their display is set to none
+ if document is overflow auto.
+ */
+ position: relative;
+}
+
+.enyo-body-fit {
+ margin: 0;
+ height: 100%;
+ /* helps prevent ios page scroll */
+ overflow: auto;
+ position: relative;
+}
+
+.enyo-no-touch-action {
+ -ms-touch-action: none;
+}
+
+/* reset */
+
+button {
+ font-size: inherit;
+ font-family: inherit;
+}
+button::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+/* user selection */
+
+.enyo-unselectable {
+ cursor: default;
+ -ms-user-select: none;
+ -webkit-user-select: none;
+ -moz-user-select: -moz-none;
+ user-select: none;
+}
+
+.enyo-unselectable::selection, .enyo-unselectable ::selection {
+ color: transparent;
+}
+
+.enyo-selectable {
+ cursor: auto;
+ -ms-user-select: element;
+ -webkit-user-select: text;
+ -moz-user-select: text;
+ user-select: text;
+}
+
+.enyo-selectable::selection, .enyo-selectable ::selection {
+ background: #3297FD;
+ color: #FFF;
+}
+
+/* layout */
+
+body .enyo-fit {
+ position: absolute;
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+}
+
+.enyo-clip {
+ overflow: hidden;
+}
+
+.enyo-border-box {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+/* compositing */
+
+.enyo-composite {
+ -webkit-transform: translateZ(0);
+ -moz-transform: translateZ(0);
+ -ms-transform: translateZ(0);
+ -o-transform: translateZ(0);
+ transform: translateZ(0);
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedomdomjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/dom.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/dom.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/dom.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,231 @@
</span><ins>+//* @public
+
+/**
+ Allow bootstrapping in environments that do not have a window object right away.
+*/
+enyo.requiresWindow = function(inFunction) {
+ inFunction();
+};
+
+enyo.dom = {
+ /**
+ Shortcut for _document.getElementById_ if _id_ is a string, otherwise returns _id_.
+ Uses _window.document_ unless a document is specified in the (optional) _doc_
+ parameter.
+
+ // find 'node' if it's a string id, or return it unchanged if it's already a node reference
+ var domNode = enyo.dom.byId(node);
+ */
+ byId: function(id, doc){
+ return (typeof id == "string") ? (doc || document).getElementById(id) : id;
+ },
+ /**
+ return string with ampersand, less-than, and greater-than characters
+ replaced with HTML entities, e.g.
+
+ '<code>"This & That"</code>'
+
+ becomes
+
+ '&lt;code&gt;"This &amp; That"&lt;/code&gt;'
+ */
+ escape: function(inText) {
+ return inText !== null ? String(inText).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>') : '';
+ },
+ /**
+ Returns an object describing the geometry of this node, like so:
+
+ {left: _offsetLeft_, top: _offsetTop_, width: _offsetWidth_, height: _offsetHeight_}
+ */
+ getBounds: function(n) {
+ if (n) {
+ return {left: n.offsetLeft, top: n.offsetTop, width: n.offsetWidth, height: n.offsetHeight};
+ }
+ else {
+ return null;
+ }
+ },
+ //* @protected
+ getComputedStyle: function(inNode) {
+ return window.getComputedStyle && inNode && window.getComputedStyle(inNode, null);
+ },
+ getComputedStyleValue: function(inNode, inProperty, inComputedStyle) {
+ var s = inComputedStyle || this.getComputedStyle(inNode);
+ return s ? s.getPropertyValue(inProperty) : null;
+ },
+ getFirstElementByTagName: function(inTagName) {
+ var e = document.getElementsByTagName(inTagName);
+ return e && e[0];
+ },
+ applyBodyFit: function() {
+ var h = this.getFirstElementByTagName("html");
+ if (h) {
+ h.className += " enyo-document-fit";
+ }
+ var b = this.getFirstElementByTagName("body");
+ if (b) {
+ b.className += " enyo-body-fit";
+ }
+ enyo.bodyIsFitting = true;
+ },
+ getWindowWidth: function() {
+ if (window.innerWidth) {
+ return window.innerWidth;
+ }
+ if (document.body && document.body.offsetWidth) {
+ return document.body.offsetWidth;
+ }
+ if (document.compatMode=='CSS1Compat' &&
+ document.documentElement &&
+ document.documentElement.offsetWidth ) {
+ return document.documentElement.offsetWidth;
+ }
+ return 320;
+ },
+ getWindowHeight: function() {
+ if (window.innerHeight) {
+ return window.innerHeight;
+ }
+ if (document.body && document.body.offsetHeight) {
+ return document.body.offsetHeight;
+ }
+ if (document.compatMode=='CSS1Compat' &&
+ document.documentElement &&
+ document.documentElement.offsetHeight ) {
+ return document.documentElement.offsetHeight;
+ }
+ return 480;
+ },
+ // moved from FittableLayout.js into common protected code
+ _ieCssToPixelValue: function(inNode, inValue) {
+ var v = inValue;
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+ var s = inNode.style;
+ // store style and runtime style values
+ var l = s.left;
+ var rl = inNode.runtimeStyle && inNode.runtimeStyle.left;
+ // then put current style in runtime style.
+ if (rl) {
+ inNode.runtimeStyle.left = inNode.currentStyle.left;
+ }
+ // apply given value and measure its pixel value
+ s.left = v;
+ v = s.pixelLeft;
+ // finally restore previous state
+ s.left = l;
+ if (rl) {
+ s.runtimeStyle.left = rl;
+ }
+ return v;
+ },
+ _pxMatch: /px/i,
+ getComputedBoxValue: function(inNode, inProp, inBoundary, inComputedStyle) {
+ var s = inComputedStyle || this.getComputedStyle(inNode);
+ if (s) {
+ return parseInt(s.getPropertyValue(inProp + "-" + inBoundary), 0);
+ } else if (inNode && inNode.currentStyle) {
+ var v = inNode.currentStyle[inProp + enyo.cap(inBoundary)];
+ if (!v.match(this._pxMatch)) {
+ v = this._ieCssToPixelValue(inNode, v);
+ }
+ return parseInt(v, 0);
+ }
+ return 0;
+ },
+ //* @public
+ //* Gets the boundaries of a node's margin or padding box.
+ calcBoxExtents: function(inNode, inBox) {
+ var s = this.getComputedStyle(inNode);
+ return {
+ top: this.getComputedBoxValue(inNode, inBox, "top", s),
+ right: this.getComputedBoxValue(inNode, inBox, "right", s),
+ bottom: this.getComputedBoxValue(inNode, inBox, "bottom", s),
+ left: this.getComputedBoxValue(inNode, inBox, "left", s)
+ };
+ },
+ //* Gets the calculated padding of a node.
+ calcPaddingExtents: function(inNode) {
+ return this.calcBoxExtents(inNode, "padding");
+ },
+ //* Gets the calculated margin of a node.
+ calcMarginExtents: function(inNode) {
+ return this.calcBoxExtents(inNode, "margin");
+ },
+ /**
+ Returns an object like `{top: 0, left: 0, bottom: 100, right: 100, height: 10, width: 10}`
+ that represents the object's position relative to `relativeToNode` (suitable for absolute
+ positioning within that parent node). Negative values mean part of the object is not visible.
+ If you leave `relativeToNode` undefined (or it is not a parent element), then the position
+ will be relative to the viewport and suitable for absolute positioning in a floating layer.
+ */
+ calcNodePosition: function(inNode, relativeToNode) {
+ // Parse upward and grab our positioning relative to the viewport
+ var top = 0,
+ left = 0,
+ node = inNode,
+ width = node.offsetWidth,
+ height = node.offsetHeight,
+ transformProp = enyo.dom.getStyleTransformProp(),
+ xregex = /translateX\((-?\d+)px\)/i,
+ yregex = /translateY\((-?\d+)px\)/i,
+ borderLeft = 0, borderTop = 0,
+ totalHeight = 0, totalWidth = 0;
+
+ if (relativeToNode) {
+ totalHeight = relativeToNode.offsetHeight;
+ totalWidth = relativeToNode.offsetWidth;
+ } else {
+ totalHeight = (document.body.parentNode.offsetHeight > this.getWindowHeight() ? this.getWindowHeight() - document.body.parentNode.scrollTop : document.body.parentNode.offsetHeight);
+ totalWidth = (document.body.parentNode.offsetWidth > this.getWindowWidth() ? this.getWindowWidth() - document.body.parentNode.scrollLeft : document.body.parentNode.offsetWidth);
+ }
+
+ if (node.offsetParent) {
+ do {
+ left += node.offsetLeft - (node.offsetParent ? node.offsetParent.scrollLeft : 0);
+ if (transformProp && xregex.test(node.style[transformProp])) {
+ left += parseInt(node.style[transformProp].replace(xregex, '$1'), 10);
+ }
+ top += node.offsetTop - (node.offsetParent ? node.offsetParent.scrollTop : 0);
+ if (transformProp && yregex.test(node.style[transformProp])) {
+ top += parseInt(node.style[transformProp].replace(yregex, '$1'), 10);
+ }
+ // Need to correct for borders if any exist on parent elements
+ if (node !== inNode) {
+ if (node.currentStyle) {
+ // Oh IE, we do so love working around your incompatibilities
+ borderLeft = parseInt(node.currentStyle.borderLeftWidth, 10);
+ borderTop = parseInt(node.currentStyle.borderTopWidth, 10);
+ } else if (window.getComputedStyle) {
+ borderLeft = parseInt(window.getComputedStyle(node, '').getPropertyValue('border-left-width'), 10);
+ borderTop = parseInt(window.getComputedStyle(node, '').getPropertyValue('border-top-width'), 10);
+ } else {
+ // No computed style options, so try the normal style object (much less robust)
+ borderLeft = parseInt(node.style.borderLeftWidth, 10);
+ borderTop = parseInt(node.style.borderTopWidth, 10);
+ }
+ if (borderLeft) {
+ left += borderLeft;
+ }
+ if (borderTop) {
+ top += borderTop;
+ }
+ }
+ } while ((node = node.offsetParent) && node !== relativeToNode);
+ }
+ return {
+ 'top': top,
+ 'left': left,
+ 'bottom': totalHeight - top - height,
+ 'right': totalWidth - left - width,
+ 'height': height,
+ 'width': width
+ };
+ },
+ //* use to modify innerHTML in a manner that's safe for Win8 applications
+ setInnerHtml: function(node, html) {
+ enyo.execUnsafeLocalFunction(function() {
+ node.innerHTML = html;
+ });
+ }
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedomdragjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/drag.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/drag.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/drag.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,266 @@
</span><ins>+/**
+ Enyo supports a cross-platform set of drag events. These events allow users
+ to write a single set of event handlers for applications that run on both
+ mobile and desktop platforms.
+
+ The following events are provided:
+
+ * "dragstart"
+ * "dragfinish"
+ * "drag"
+ * "drop"
+ * "dragover"
+ * "dragout"
+ * "hold"
+ * "release"
+ * "holdpulse"
+ * "flick"
+
+ For more information on these events, see the documentation on
+ [User Input](https://github.com/enyojs/enyo/wiki/User-Input) in the Enyo
+ Developer Guide.
+*/
+
+//* @protected
+enyo.dispatcher.features.push(
+ function(e) {
+ // NOTE: beware of properties in enyo.gesture inadvertently mapped to event types
+ if (enyo.gesture.drag[e.type]) {
+ return enyo.gesture.drag[e.type](e);
+ }
+ }
+);
+
+//* @public
+enyo.gesture.drag = {
+ //* @protected
+ hysteresisSquared: 16,
+ holdPulseDelay: 200,
+ trackCount: 5,
+ minFlick: 0.1,
+ minTrack: 8,
+ down: function(e) {
+ // tracking if the mouse is down
+ //enyo.log("tracking ON");
+ // Note: 'tracking' flag indicates interest in mousemove, it's turned off
+ // on mouseup
+ // make sure to stop dragging in case the up event was not received.
+ this.stopDragging(e);
+ this.cancelHold();
+ this.target = e.target;
+ this.startTracking(e);
+ this.beginHold(e);
+ },
+ move: function(e) {
+ if (this.tracking) {
+ this.track(e);
+ // If the mouse is not down and we're tracking a drag, abort.
+ // this error condition can occur on IE/Webkit after interaction with a scrollbar.
+ if (!e.which) {
+ this.stopDragging(e);
+ this.cancelHold();
+ this.tracking = false;
+ //enyo.log("enyo.gesture.drag: mouse must be down to drag.");
+ return;
+ }
+ if (this.dragEvent) {
+ this.sendDrag(e);
+ } else if (this.dy*this.dy + this.dx*this.dx >= this.hysteresisSquared) {
+ this.sendDragStart(e);
+ this.cancelHold();
+ }
+ }
+ },
+ up: function(e) {
+ this.endTracking(e);
+ this.stopDragging(e);
+ this.cancelHold();
+ },
+ leave: function(e) {
+ if (this.dragEvent) {
+ this.sendDragOut(e);
+ }
+ },
+ stopDragging: function(e) {
+ if (this.dragEvent) {
+ this.sendDrop(e);
+ var handled = this.sendDragFinish(e);
+ this.dragEvent = null;
+ return handled;
+ }
+ },
+ makeDragEvent: function(inType, inTarget, inEvent, inInfo) {
+ var adx = Math.abs(this.dx), ady = Math.abs(this.dy);
+ var h = adx > ady;
+ // suggest locking if off-axis < 22.5 degrees
+ var l = (h ? ady/adx : adx/ady) < 0.414;
+ var e = {
+ type: inType,
+ dx: this.dx,
+ dy: this.dy,
+ ddx: this.dx - this.lastDx,
+ ddy: this.dy - this.lastDy,
+ xDirection: this.xDirection,
+ yDirection: this.yDirection,
+ pageX: inEvent.pageX,
+ pageY: inEvent.pageY,
+ clientX: inEvent.clientX,
+ clientY: inEvent.clientY,
+ horizontal: h,
+ vertical: !h,
+ lockable: l,
+ target: inTarget,
+ dragInfo: inInfo,
+ ctrlKey: inEvent.ctrlKey,
+ altKey: inEvent.altKey,
+ metaKey: inEvent.metaKey,
+ shiftKey: inEvent.shiftKey,
+ srcEvent: inEvent.srcEvent
+ };
+ //Fix for IE8, which doesn't include pageX and pageY properties
+ if(enyo.platform.ie==8 && e.target) {
+ e.pageX = e.clientX + e.target.scrollLeft;
+ e.pageY = e.clientY + e.target.scrollTop;
+ }
+ e.preventDefault = enyo.gesture.preventDefault;
+ e.disablePrevention = enyo.gesture.disablePrevention;
+ return e;
+ },
+ sendDragStart: function(e) {
+ //enyo.log("dragstart");
+ this.dragEvent = this.makeDragEvent("dragstart", this.target, e);
+ enyo.dispatch(this.dragEvent);
+ },
+ sendDrag: function(e) {
+ //enyo.log("sendDrag to " + this.dragEvent.target.id + ", over to " + e.target.id);
+ // send dragOver event to the standard event target
+ var synth = this.makeDragEvent("dragover", e.target, e, this.dragEvent.dragInfo);
+ enyo.dispatch(synth);
+ // send drag event to the drag source
+ synth.type = "drag";
+ synth.target = this.dragEvent.target;
+ enyo.dispatch(synth);
+ },
+ sendDragFinish: function(e) {
+ //enyo.log("dragfinish");
+ var synth = this.makeDragEvent("dragfinish", this.dragEvent.target, e, this.dragEvent.dragInfo);
+ synth.preventTap = function() {
+ if (e.preventTap) {
+ e.preventTap();
+ }
+ };
+ enyo.dispatch(synth);
+ },
+ sendDragOut: function(e) {
+ var synth = this.makeDragEvent("dragout", e.target, e, this.dragEvent.dragInfo);
+ enyo.dispatch(synth);
+ },
+ sendDrop: function(e) {
+ var synth = this.makeDragEvent("drop", e.target, e, this.dragEvent.dragInfo);
+ synth.preventTap = function() {
+ if (e.preventTap) {
+ e.preventTap();
+ }
+ };
+ enyo.dispatch(synth);
+ },
+ startTracking: function(e) {
+ this.tracking = true;
+ // note: use clientX/Y to be compatible with ie8
+ this.px0 = e.clientX;
+ this.py0 = e.clientY;
+ this.flickInfo = {startEvent: e, moves: []};
+ this.track(e);
+ },
+ track: function(e) {
+ this.lastDx = this.dx;
+ this.lastDy = this.dy;
+ this.dx = e.clientX - this.px0;
+ this.dy = e.clientY - this.py0;
+ this.xDirection = this.calcDirection(this.dx - this.lastDx, 0);
+ this.yDirection = this.calcDirection(this.dy - this.lastDy, 0);
+ //
+ var ti = this.flickInfo;
+ ti.moves.push({
+ x: e.clientX,
+ y: e.clientY,
+ t: enyo.now()
+ });
+ // track specified # of points
+ if (ti.moves.length > this.trackCount) {
+ ti.moves.shift();
+ }
+ },
+ endTracking: function(e) {
+ this.tracking = false;
+ var ti = this.flickInfo;
+ var moves = ti && ti.moves;
+ if (moves && moves.length > 1) {
+ // note: important to use up time to reduce flick
+ // velocity based on time between move and up.
+ var l = moves[moves.length-1];
+ var n = enyo.now();
+ // take the greatest of flick between each tracked move and last move
+ for (var i=moves.length-2, dt=0, x1=0, y1=0, x=0, y=0, sx=0, sy=0, m; (m=moves[i]); i--) {
+ // this flick (this move - last move) / (this time - last time)
+ dt = n - m.t;
+ x1 = (l.x - m.x) / dt;
+ y1 = (l.y - m.y) / dt;
+ // establish flick direction
+ sx = sx || (x1 < 0 ? -1 : (x1 > 0 ? 1 : 0));
+ sy = sy || (y1 < 0 ? -1 : (y1 > 0 ? 1 : 0));
+ // if either axis is a greater flick than previously recorded use this one
+ if ((x1 * sx > x * sx) || (y1 * sy > y * sy)) {
+ x = x1;
+ y = y1;
+ }
+ }
+ var v = Math.sqrt(x*x + y*y);
+ if (v > this.minFlick) {
+ // generate the flick using the start event so it has those coordinates
+ this.sendFlick(ti.startEvent, x, y, v);
+ }
+ }
+ this.flickInfo = null;
+ },
+ calcDirection: function(inNum, inDefault) {
+ return inNum > 0 ? 1 : (inNum < 0 ? -1 : inDefault);
+ },
+ beginHold: function(e) {
+ this.holdStart = enyo.now();
+ this.holdJob = setInterval(enyo.bind(this, "sendHoldPulse", e), this.holdPulseDelay);
+ },
+ cancelHold: function() {
+ clearInterval(this.holdJob);
+ this.holdJob = null;
+ if (this.sentHold) {
+ this.sentHold = false;
+ this.sendRelease(this.holdEvent);
+ }
+ },
+ sendHoldPulse: function(inEvent) {
+ if (!this.sentHold) {
+ this.sentHold = true;
+ this.sendHold(inEvent);
+ }
+ var e = enyo.gesture.makeEvent("holdpulse", inEvent);
+ e.holdTime = enyo.now() - this.holdStart;
+ enyo.dispatch(e);
+ },
+ sendHold: function(inEvent) {
+ this.holdEvent = inEvent;
+ var e = enyo.gesture.makeEvent("hold", inEvent);
+ enyo.dispatch(e);
+ },
+ sendRelease: function(inEvent) {
+ var e = enyo.gesture.makeEvent("release", inEvent);
+ enyo.dispatch(e);
+ },
+ sendFlick: function(inEvent, inX, inY, inV) {
+ var e = enyo.gesture.makeEvent("flick", inEvent);
+ e.xVelocity = inX;
+ e.yVelocity = inY;
+ e.velocity = inV;
+ enyo.dispatch(e);
+ }
+};
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedomgesturejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/gesture.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/gesture.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/gesture.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,172 @@
</span><ins>+//* @public
+/**
+ Enyo supports a set of normalized events that work similarly across all
+ supported platforms. These events are provided so that users can write a
+ single set of event handlers for applications that run on both mobile and
+ desktop platforms. They are needed because desktop and mobile platforms
+ handle basic input differently.
+
+ For more information on normalized input events and their associated
+ properties, see the documentation on
+ [User Input](https://github.com/enyojs/enyo/wiki/User-Input) in the Enyo
+ Developer Guide.
+*/
+enyo.gesture = {
+ //* @protected
+ eventProps: ["target", "relatedTarget", "clientX", "clientY", "pageX", "pageY",
+ "screenX", "screenY", "altKey", "ctrlKey", "metaKey", "shiftKey",
+ "detail", "identifier", "dispatchTarget", "which", "srcEvent"],
+ makeEvent: function(inType, inEvent) {
+ var e = {type: inType};
+ for (var i=0, p; (p=this.eventProps[i]); i++) {
+ e[p] = inEvent[p];
+ }
+ e.srcEvent = e.srcEvent || inEvent;
+ e.preventDefault = this.preventDefault;
+ e.disablePrevention = this.disablePrevention;
+ //
+ // normalize event.which and event.pageX/event.pageY
+ // Note that while "which" works in IE9, it is broken for mousemove. Therefore,
+ // in IE, use window.event.button
+ if (enyo.platform.ie < 10) {
+ //Fix for IE8, which doesn't include pageX and pageY properties
+ if(enyo.platform.ie==8 && e.target) {
+ e.pageX = e.clientX + e.target.scrollLeft;
+ e.pageY = e.clientY + e.target.scrollTop;
+ }
+ var b = window.event && window.event.button;
+ // multi-button not supported, priority: left, right, middle
+ // (note: IE bitmask is 1=left, 2=right, 4=center);
+ e.which = b & 1 ? 1 : (b & 2 ? 2 : (b & 4 ? 3 : 0));
+ } else if (enyo.platform.webos || window.PalmSystem) {
+ // Temporary fix for owos: it does not currently supply 'which' on move events
+ // and the user agent string doesn't identify itself so we test for PalmSystem
+ if (e.which === 0) {
+ e.which = 1;
+ }
+ }
+ return e;
+ },
+ down: function(inEvent) {
+ // cancel any hold since it's possible in corner cases to get a down without an up
+ var e = this.makeEvent("down", inEvent);
+ enyo.dispatch(e);
+ this.downEvent = e;
+ },
+ move: function(inEvent) {
+ var e = this.makeEvent("move", inEvent);
+ // include delta and direction v. down info in move event
+ e.dx = e.dy = e.horizontal = e.vertical = 0;
+ if (e.which && this.downEvent) {
+ e.dx = inEvent.clientX - this.downEvent.clientX;
+ e.dy = inEvent.clientY - this.downEvent.clientY;
+ e.horizontal = Math.abs(e.dx) > Math.abs(e.dy);
+ e.vertical = !e.horizontal;
+ }
+ enyo.dispatch(e);
+ },
+ up: function(inEvent) {
+ var e = this.makeEvent("up", inEvent);
+ var tapPrevented = false;
+ e.preventTap = function() {
+ tapPrevented = true;
+ };
+ enyo.dispatch(e);
+ if (!tapPrevented && this.downEvent && this.downEvent.which == 1) {
+ this.sendTap(e);
+ }
+ this.downEvent = null;
+ },
+ over: function(inEvent) {
+ enyo.dispatch(this.makeEvent("enter", inEvent));
+ },
+ out: function(inEvent) {
+ enyo.dispatch(this.makeEvent("leave", inEvent));
+ },
+ sendTap: function(inEvent) {
+ // The common ancestor for the down/up pair is the origin for the tap event
+ var t = this.findCommonAncestor(this.downEvent.target, inEvent.target);
+ if (t) {
+ var e = this.makeEvent("tap", inEvent);
+ e.target = t;
+ enyo.dispatch(e);
+ }
+ },
+ findCommonAncestor: function(inA, inB) {
+ var p = inB;
+ while (p) {
+ if (this.isTargetDescendantOf(inA, p)) {
+ return p;
+ }
+ p = p.parentNode;
+ }
+ },
+ isTargetDescendantOf: function(inChild, inParent) {
+ var c = inChild;
+ while(c) {
+ if (c == inParent) {
+ return true;
+ }
+ c = c.parentNode;
+ }
+ }
+};
+
+//* @protected
+
+// installed on events and called in event context
+enyo.gesture.preventDefault = function() {
+ if (this.srcEvent) {
+ this.srcEvent.preventDefault();
+ }
+};
+
+enyo.gesture.disablePrevention = function() {
+ this.preventDefault = enyo.nop;
+ if (this.srcEvent) {
+ this.srcEvent.preventDefault = enyo.nop;
+ }
+};
+
+enyo.dispatcher.features.push(
+ function(e) {
+ // NOTE: beware of properties in enyo.gesture inadvertently mapped to event types
+ if (enyo.gesture.events[e.type]) {
+ return enyo.gesture.events[e.type](e);
+ }
+ }
+);
+
+enyo.gesture.events = {
+ mousedown: function(e) {
+ enyo.gesture.down(e);
+ },
+ mouseup: function(e) {
+ enyo.gesture.up(e);
+ },
+ mousemove: function(e) {
+ enyo.gesture.move(e);
+ },
+ mouseover: function(e) {
+ enyo.gesture.over(e);
+ },
+ mouseout: function(e) {
+ enyo.gesture.out(e);
+ }
+};
+
+// Firefox mousewheel handling
+enyo.requiresWindow(function() {
+ if (document.addEventListener) {
+ document.addEventListener("DOMMouseScroll", function(inEvent) {
+ var e = enyo.clone(inEvent);
+ e.preventDefault = function() {
+ inEvent.preventDefault();
+ };
+ e.type = "mousewheel";
+ var p = e.VERTICAL_AXIS == e.axis ? "wheelDeltaY" : "wheelDeltaX";
+ e[p] = e.detail * -40;
+ enyo.dispatch(e);
+ }, false);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedommodaljs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/modal.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/modal.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/modal.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+//* @protected
+
+/**
+ Event modal capture feature: capture events to a specific
+ control via enyo.dispatcher.capture(inControl, inShouldForward)
+ release events via enyo.dispatcher.release()
+*/
+enyo.dispatcher.features.push(function(e) {
+ var c = e.dispatchTarget;
+ var wants = this.captureTarget && !this.noCaptureEvents[e.type];
+ var needs = wants && !(c && c.isDescendantOf && c.isDescendantOf(this.captureTarget));
+ if (needs) {
+ var c1 = e.captureTarget = this.captureTarget;
+ // NOTE: We do not want releasing capture while an event is being processed to alter
+ // the way the event propagates. Therefore decide if the event should forward
+ // before the capture target receives the event (since it may release capture).
+ var shouldForward = (this.autoForwardEvents[e.type] || this.forwardEvents);
+ this.dispatchBubble(e, c1);
+ if (!shouldForward) {
+ e.preventDispatch = true;
+ }
+ }
+});
+
+//
+// NOTE: This object is a plug-in; these methods should
+// be called on _enyo.dispatcher_, and not on the plug-in itself.
+//
+enyo.mixin(enyo.dispatcher, {
+ noCaptureEvents: {load: 1, unload:1, error: 1},
+ autoForwardEvents: {leave: 1, resize: 1},
+ captures: [],
+ //* Capture events for `inTarget` and optionally forward them
+ capture: function(inTarget, inShouldForward) {
+ var info = {target: inTarget, forward: inShouldForward};
+ this.captures.push(info);
+ this.setCaptureInfo(info);
+ },
+ //* Release the last captured event
+ release: function() {
+ this.captures.pop();
+ this.setCaptureInfo(this.captures[this.captures.length-1]);
+ },
+ //* Set the information for a captured event
+ setCaptureInfo: function(inInfo) {
+ this.captureTarget = inInfo && inInfo.target;
+ this.forwardEvents = inInfo && inInfo.forward;
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedompackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+enyo.depends(
+ "dom.css",
+ "dom.js",
+ "transform.js",
+ "Control.js",
+ "platform.js",
+ "animation.js",
+ "phonegap.js",
+ "dispatcher.js",
+ "preview.js",
+ "modal.js",
+ "gesture.js",
+ "drag.js",
+ "transition.js"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedomphonegapjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/phonegap.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/phonegap.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/phonegap.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+/**
+Listens for PhoneGap specific events
+
+Events are exposed through the [Signals](#enyo.Signals) kind by adding callback handlers.
+
+Example:
+
+enyo.kind({
+ name: "App",
+ components: [
+ {kind: "Signals", ondeviceready: "deviceready"},
+ ...
+ ],
+ deviceready: function() {
+ // PhoneGap API exists at this point forward
+ }
+});
+
+List of PhoneGap events detailed on the [PhoneGap Docs](http://docs.phonegap.com/en/1.6.0/phonegap_events_events.md.html#Events)
+*/
+//* @protected
+(function(){
+ if (window.cordova || window.PhoneGap) {
+ var pge = [
+ "deviceready",
+ "pause",
+ "resume",
+ "online",
+ "offline",
+ "backbutton",
+ "batterycritical",
+ "batterylow",
+ "batterystatus",
+ "menubutton",
+ "searchbutton",
+ "startcallbutton",
+ "endcallbutton",
+ "volumedownbutton",
+ "volumeupbutton"
+ ];
+ for (var i=0, e; (e=pge[i]); i++) {
+ // some phonegap events have no type, so enyo.dispatch fails
+ document.addEventListener(e, enyo.bind(enyo.Signals, "send", "on" + e), false);
+ }
+ }
+})();
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedomplatformjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/platform.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/platform.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/platform.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,90 @@
</span><ins>+/**
+ Determines OS versions of platforms that need special treatment.
+ Can have one of the following properties:
+
+ * android
+ * androidChrome (Chrome on Android, standard starting in 4.1)
+ * androidFirefox
+ * ie
+ * ios
+ * webos
+ * blackberry
+ * safari (desktop version)
+ * chrome (desktop version)
+ * firefox (desktop version)
+
+ If the property is defined, its value will be the major version number
+ of the platform.
+
+ Example:
+
+ // android 2 does not have 3d css
+ if (enyo.platform.android < 3) {
+ t = "translate(30px, 50px)";
+ } else {
+ t = "translate3d(30px, 50px, 0)";
+ }
+ this.applyStyle("-webkit-transform", t);
+*/
+enyo.platform = {
+ //* True if the platform has native single finger events
+ touch: Boolean(("ontouchstart" in window) || window.navigator.msMaxTouchPoints),
+ //* True if the platform has native double finger events
+ gesture: Boolean(("ongesturestart" in window) || window.navigator.msMaxTouchPoints)
+};
+
+//* @protected
+(function() {
+ var ua = navigator.userAgent;
+ var ep = enyo.platform;
+ var platforms = [
+ // Android 4+ using Chrome
+ {platform: "androidChrome", regex: /Android .* Chrome\/(\d+)[.\d]+/},
+ // Android 2 - 4
+ {platform: "android", regex: /Android (\d+)/},
+ // Kindle Fire
+ // Force version to 2, (desktop mode does not list android version)
+ {platform: "android", regex: /Silk\/1./, forceVersion: 2, extra: {silk: 1}},
+ // Kindle Fire HD
+ // Force version to 4
+ {platform: "android", regex: /Silk\/2./, forceVersion: 4, extra: {silk: 2}},
+ // Windows Phone 7 - 8
+ {platform: "windowsPhone", regex: /Windows Phone (?:OS )?(\d+)[.\d]+/},
+ // IE 8 - 10
+ {platform: "ie", regex: /MSIE (\d+)/},
+ // iOS 3 - 5
+ // Apple likes to make this complicated
+ {platform: "ios", regex: /iP(?:hone|ad;(?: U;)? CPU) OS (\d+)/},
+ // webOS 1 - 3
+ {platform: "webos", regex: /(?:web|hpw)OS\/(\d+)/},
+ // desktop Safari
+ {platform: "safari", regex: /Version\/(\d+)[.\d]+\s+Safari/},
+ // desktop Chrome
+ {platform: "chrome", regex: /Chrome\/(\d+)[.\d]+/},
+ // Firefox on Android
+ {platform: "androidFirefox", regex: /Android;.*Firefox\/(\d+)/},
+ // FirefoxOS
+ {platform: "firefoxOS", regex: /Mobile;.*Firefox\/(\d+)/},
+ // desktop Firefox
+ {platform: "firefox", regex: /Firefox\/(\d+)/},
+ // Blackberry 10+
+ {platform: "blackberry", regex: /BB1\d;.*Version\/(\d+\.\d+)/}
+ ];
+ for (var i = 0, p, m, v; (p = platforms[i]); i++) {
+ m = p.regex.exec(ua);
+ if (m) {
+ if (p.forceVersion) {
+ v = p.forceVersion;
+ } else {
+ v = Number(m[1]);
+ }
+ ep[p.platform] = v;
+ if (p.extra) {
+ enyo.mixin(ep, p.extra);
+ }
+ break;
+ }
+ }
+ // these platforms only allow one argument for console.log
+ enyo.dumbConsole = Boolean(ep.android || ep.ios || ep.webos);
+})();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedompreviewjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/preview.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/preview.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/preview.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+/**
+ Dispatcher preview feature: allow control ancestors of the event
+ target a chance (eldest first) to react via implementing "previewDomEvent."
+*/
+//* @protected
+(function() {
+ var fn = "previewDomEvent";
+ //
+ var preview = {
+ feature: function(e) {
+ preview.dispatch(e, e.dispatchTarget);
+ },
+ dispatch: function(e, c) {
+ var l$ = this.buildLineage(c);
+ // handlers return true to abort preview and prevent default event processing.
+ for (var i=0, l; (l=l$[i]); i++) {
+ if (l[fn] && l[fn](e) === true) {
+ e.preventDispatch = true;
+ return;
+ }
+ }
+ },
+ // we ascend making a list of enyo controls
+ // NOTE: the control is considered its own ancestor
+ buildLineage: function(inControl) {
+ var l = [], c = inControl;
+ while (c) {
+ l.unshift(c);
+ c = c.parent;
+ }
+ return l;
+ }
+ };
+ //
+ enyo.dispatcher.features.push(preview.feature);
+})();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedomtransformjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/transform.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/transform.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/transform.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,139 @@
</span><ins>+//* @protected
+(function() {
+ enyo.dom.calcCanAccelerate = function() {
+ /* Android 2 is a liar: it does NOT support 3D transforms, even though Perspective is the best check */
+ if (enyo.platform.android <= 2) {
+ return false;
+ }
+ var p$ = ["perspective", "WebkitPerspective", "MozPerspective", "msPerspective", "OPerspective"];
+ for (var i=0, p; (p=p$[i]); i++) {
+ if (typeof document.body.style[p] != "undefined") {
+ return true;
+ }
+ }
+ return false;
+ };
+ var cssTransformProps = ["transform", "-webkit-transform", "-moz-transform", "-ms-transform", "-o-transform"];
+ var styleTransformProps = ["transform", "webkitTransform", "MozTransform", "msTransform", "OTransform"];
+ enyo.dom.getCssTransformProp = function() {
+ if (this._cssTransformProp) {
+ return this._cssTransformProp;
+ }
+ var i = enyo.indexOf(this.getStyleTransformProp(), styleTransformProps);
+ return this._cssTransformProp = cssTransformProps[i];
+ };
+ enyo.dom.getStyleTransformProp = function() {
+ if (this._styleTransformProp || !document.body) {
+ return this._styleTransformProp;
+ }
+ for (var i = 0, p; (p = styleTransformProps[i]); i++) {
+ if (typeof document.body.style[p] != "undefined") {
+ return this._styleTransformProp = p;
+ }
+ }
+ };
+ enyo.dom.domTransformsToCss = function(inTransforms) {
+ var n, v, text = '';
+ for (n in inTransforms) {
+ v = inTransforms[n];
+ if ((v !== null) && (v !== undefined) && (v !== "")) {
+ text += n + '(' + v + ') ';
+ }
+ }
+ return text;
+ };
+ enyo.dom.transformsToDom = function(inControl) {
+ var t = this.domTransformsToCss(inControl.domTransforms);
+ var st = inControl.hasNode() ? inControl.node.style : null;
+ var ds = inControl.domStyles;
+ var sp = this.getStyleTransformProp();
+ var cp = this.getCssTransformProp();
+ if (sp && cp) {
+ ds[cp] = t;
+ if (st) {
+ st[sp] = t;
+ } else {
+ inControl.domStylesChanged();
+ }
+ }
+ };
+ //* @public
+ /**
+ Returns true if the platform supports CSS3 Transforms
+ */
+ enyo.dom.canTransform = function() {
+ return Boolean(this.getStyleTransformProp());
+ };
+ /**
+ Returns true if platform supports CSS3 3D Transforms.
+
+ Typically used like this:
+
+ if (enyo.dom.canAccelerate()) {
+ enyo.dom.transformValue(this.$.slidingThing, "translate3d", x + "," + y + "," + "0")
+ } else {
+ enyo.dom.transformValue(this.$.slidingThing, "translate", x + "," + y);
+ }
+
+ */
+ enyo.dom.canAccelerate = function() {
+ return this.accelerando !== undefined ? this.accelerando: document.body && (this.accelerando = this.calcCanAccelerate());
+ };
+ /**
+ Applies a series of transforms to _inControl_, using the platform's prefixed transform property.
+
+ **Note:** Transforms are not commutative, so order is important
+
+ Transform values are updated by successive calls:
+
+ enyo.dom.transform(control, {translate: "30px, 40px", scale: 2, rotate: "20deg"});
+ enyo.dom.transform(control, {scale: 3, skewX: "-30deg"});
+
+ is equivalent to:
+
+ enyo.dom.transform(control, {translate: "30px, 40px", scale: 3, rotate: "20deg", skewX: "-30deg"});
+
+ When applying these transforms in webkit browser, this is equivalent to:
+
+ control.applyStyle("-webkit-transform", "translate(30px, 40px) scale(3) rotate(20deg) skewX(-30deg)");
+
+ And in firefox, this is equivalent to:
+
+ control.applyStyle("-moz-transform", "translate(30px, 40px) scale(3) rotate(20deg) skewX(-30deg)");
+
+ */
+ enyo.dom.transform = function(inControl, inTransforms) {
+ var d = inControl.domTransforms = inControl.domTransforms || {};
+ enyo.mixin(d, inTransforms);
+ this.transformsToDom(inControl);
+ };
+
+ /**
+ Apply a single transform to _inControl_.
+
+ Example:
+
+ tap: function(inSender, inEvent) {
+ var c = inEvent.originator;
+ var r = c.rotation || 0;
+ r = (r + 45) % 360;
+ c.rotation = r;
+ enyo.dom.transformValue(c, "rotate", r);
+ }
+
+ This will rotate the tapped control by 45 degrees clockwise.
+ */
+ enyo.dom.transformValue = function(inControl, inTransform, inValue) {
+ var d = inControl.domTransforms = inControl.domTransforms || {};
+ d[inTransform] = inValue;
+ this.transformsToDom(inControl);
+ };
+ //* @protected
+ /**
+ Applies a transform that should trigger GPU compositing for _inControl_
+ */
+ enyo.dom.accelerate = function(inControl, inValue) {
+ var v = inValue == "auto" ? this.canAccelerate() : inValue;
+ this.transformValue(inControl, "translateZ", v ? 0 : null);
+ };
+})();
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcedomtransitionjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/dom/transition.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/dom/transition.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/dom/transition.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+enyo.dom.transition = (enyo.platform.ios || enyo.platform.android || enyo.platform.chrome || enyo.platform.androidChrome || enyo.platform.safari)
+ ? "-webkit-transition"
+ : (enyo.platform.firefox || enyo.platform.firefoxOS || enyo.platform.androidFirefox)
+ ? "-moz-transition"
+ : "transition";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcekernelComponentjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/kernel/Component.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/kernel/Component.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/kernel/Component.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,547 @@
</span><ins>+/**
+ _enyo.Component_ is the fundamental building block for Enyo applications.
+ Components are designed to fit together, so that complex behaviors may be
+ fashioned from smaller bits of functionality.
+
+ Component constructors take a single argument (sometimes called a
+ _Component configuration_), a JavaScript object that defines various
+ properties to be initialized on the Component. For example:
+
+ // create a new component, initialize its name property to 'me'.
+ var c = new enyo.Component({
+ name: "me"
+ });
+
+ When a Component is instantiated, items configured in its _components_
+ property are instantiated, too:
+
+ // create a new component, which itself has a component
+ var c = new enyo.Component({
+ name: "me",
+ components: [
+ {kind: "Component", name: "other"}
+ ]
+ });
+
+ In this case, when _me_ is created, _other_ is also created, and we say that
+ _me owns other_. In other words, the _owner_ property of _other_ equals
+ _me_. Notice that you can specify the _kind_ of _other_ explicitly in its
+ configuration block, to tell _me_ what constructor to use to create _other_.
+
+ Note that _kind_ values may be references to actual kinds or string-names of
+ kinds. Kind names that do not resolve directly to kinds are looked up in
+ default namespaces. In this case, _kind: "Component"_ resolves to
+ _enyo.Component_.
+
+ To move a component, use the _setOwner_ method to change the component's owner.
+ If you want to make a component unowned, use _setOwner(null)_.
+
+ If you make changes to _enyo.Component_, be sure to add or update the
+ appropriate [unit tests](https://github.com/enyojs/enyo/tree/master/tools/test/core/tests).
+
+ For more information, see the documentation on
+ [Components](https://github.com/enyojs/enyo/wiki/Creating-Components)
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.Component",
+ kind: enyo.Object,
+ published: {
+ /**
+ A unique name for the component within its owner. This is used to
+ set the access name in the owner's _$_ hash. If not specified, a
+ default name will be provided based on the name of the object's
+ kind, optionally with a number suffix if more than one instance
+ exists in the owner.
+ */
+ name: "",
+ /**
+ A unique id for the component, usually automatically generated based
+ on its position within the component hierarchy, although it may also
+ be directly specified. _enyo.Control_ uses this id value for the DOM
+ id attribute.
+ */
+ id: "",
+ /**
+ The component that owns this component. It is usually implicitly
+ defined during creation based on the _createComponent_ call or
+ _components_ hash.
+ */
+ owner: null
+ },
+ //* @protected
+ statics: {
+ // for memoizing kind-prefix names in nameComponent
+ _kindPrefixi: {},
+ // for naming the unnamed
+ _unnamedKindNumber: 0
+ },
+ defaultKind: "Component",
+ handlers: {},
+ toString: function() {
+ return this.kindName;
+ },
+ constructor: function() {
+ // initialize instance objects
+ this._componentNameMap = {};
+ this.$ = {};
+ this.inherited(arguments);
+ },
+ constructed: function(inProps) {
+ // entire constructor chain has fired, now start creation chain
+ // process instance properties
+ this.importProps(inProps);
+ // perform initialization
+ this.create();
+ },
+ //* @protected
+ importProps: function(inProps) {
+ if (inProps) {
+ for (var n in inProps) {
+ this[n] = inProps[n];
+ }
+ }
+ this.handlers = enyo.mixin(enyo.clone(this.kindHandlers), this.handlers);
+ },
+ create: function() {
+ this.ownerChanged();
+ this.initComponents();
+ },
+ initComponents: function() {
+ // The _components_ property in kind declarations is renamed to
+ // _kindComponents_ by the Component subclass mechanism. This makes it
+ // easy for the developer to distinguish kindComponents from the components
+ // in _this.components_, without having to worry about the actual difference.
+ //
+ // Specifically, the difference is that kindComponents are constructed as
+ // owned by this control (whereas components in _this.components_ are not).
+ // In addition, kindComponents are marked with the _isChrome: true_ flag.
+ this.createChrome(this.kindComponents);
+ this.createClientComponents(this.components);
+ },
+ createChrome: function(inComponents) {
+ this.createComponents(inComponents, {isChrome: true});
+ },
+ createClientComponents: function(inComponents) {
+ this.createComponents(inComponents, {owner: this.getInstanceOwner()});
+ },
+ getInstanceOwner: function() {
+ return (!this.owner || this.owner.notInstanceOwner) ? this : this.owner;
+ },
+ //* @public
+ /**
+ Removes this component from its owner (sets _owner_ to null) and does
+ any cleanup. The component is flagged with a _destroyed: true_ property.
+ Usually the component will be suitable for garbage collection after
+ being destroyed, unless user code keeps a reference to it.
+ */
+ destroy: function() {
+ this.destroyComponents();
+ this.setOwner(null);
+ // JS objects are never truly destroyed (GC'd) until all references are gone,
+ // we might have some delayed action on this object that needs to have access
+ // to this flag.
+ this.destroyed = true;
+ },
+ /**
+ Destroys all owned components.
+ */
+ destroyComponents: function() {
+ enyo.forEach(this.getComponents(), function(c) {
+ // This local components list may be stale as components
+ // we owned when the loop started could have been destroyed
+ // by containers. Avoid redestroying components by testing
+ // destroyed flag.
+ if (!c.destroyed) {
+ c.destroy();
+ }
+ });
+ },
+ //* @protected
+ makeId: function() {
+ var delim = "_", pre = this.owner && this.owner.getId();
+ var baseName = this.name || ("@@" + (++enyo.Component._unnamedKindNumber));
+ return (pre ? pre + delim : "") + baseName;
+ },
+ ownerChanged: function(inOldOwner) {
+ if (inOldOwner) {
+ inOldOwner.removeComponent(this);
+ }
+ if (this.owner) {
+ this.owner.addComponent(this);
+ }
+ if (!this.id) {
+ this.id = this.makeId();
+ }
+ //this.id = this.makeId();
+ },
+ nameComponent: function(inComponent) {
+ var prefix = enyo.Component.prefixFromKindName(inComponent.kindName);
+ // get last memoized name index
+ var n, i = this._componentNameMap[prefix] || 0;
+ // find an available name
+ do {
+ n = prefix + (++i > 1 ? String(i) : "");
+ } while (this.$[n]);
+ // memoize next likely-unique id tag for this prefix
+ this._componentNameMap[prefix] = Number(i);
+ // set and return
+ return inComponent.name = n;
+ },
+ /**
+ Adds _inComponent_ to the list of components owned by the current
+ component (i.e., _this.$_).
+ */
+ addComponent: function(inComponent) {
+ var n = inComponent.getName();
+ if (!n) {
+ n = this.nameComponent(inComponent);
+ }
+ if (this.$[n]) {
+ this.warn('Duplicate component name "' + n + '" in owner "' + this.id + '" violates ' +
+ 'unique-name-under-owner rule, replacing existing component in the hash and continuing, ' +
+ 'but this is an error condition and should be fixed.');
+ }
+ this.$[n] = inComponent;
+ },
+ //* Removes _inComponent_ from the list of components owned by the current
+ //* component (i.e., _this.$_).
+ removeComponent: function(inComponent) {
+ delete this.$[inComponent.getName()];
+ },
+ //* @public
+ /**
+ Returns an array of owned components; in other words, converts the _$_
+ hash into an array and returns the array.
+ */
+ getComponents: function() {
+ var results = [];
+ for (var n in this.$) {
+ results.push(this.$[n]);
+ }
+ return results;
+ },
+ //* @protected
+ adjustComponentProps: function(inProps) {
+ if (this.defaultProps) {
+ enyo.mixin(inProps, this.defaultProps);
+ }
+ inProps.kind = inProps.kind || inProps.isa || this.defaultKind;
+ inProps.owner = inProps.owner || this;
+ },
+ _createComponent: function(inInfo, inMoreInfo) {
+ if (!inInfo.kind && ("kind" in inInfo)) {
+ throw "enyo.create: Attempt to create a null kind. Check dependencies for [" + inInfo.name + "].";
+ }
+ // CAVEAT: inInfo and inMoreInfo are copied before mutation, but it's only a shallow copy
+ var props = enyo.mixin(enyo.clone(inMoreInfo), inInfo);
+ this.adjustComponentProps(props);
+ return enyo.Component.create(props);
+ },
+ //* @public
+ /**
+ Creates and returns a component as defined by the combination of
+ _inInfo_ and _inMoreInfo_. Properties in _inInfo_ override properties in
+ _inMoreInfo_.
+
+ The created component passes through initialization machinery provided
+ by the creating component, which may supply special handling.
+ Unless the owner is explicitly specified, the new component will be
+ owned by the instance on which _createComponent_ is called.
+
+ // Create a new component named _dynamic_ owned by _this_
+ // (will be available as this.$.dynamic).
+ this.createComponent({name: "dynamic"});
+
+ // Create a new component named _another_ owned by _other_
+ // (will be available as other.$.another).
+ this.createComponent({name: "another"}, {owner: other});
+ */
+ createComponent: function(inInfo, inMoreInfo) {
+ // createComponent and createComponents both delegate to the protected method (_createComponent),
+ // allowing overrides to customize createComponent and createComponents separately.
+ return this._createComponent(inInfo, inMoreInfo);
+ },
+ /**
+ Creates Components as defined by the array of configurations _inInfos_.
+ Each configuration in _inInfos_ is combined with _inCommonInfo_ as
+ described in _createComponent_.
+
+ _createComponents_ returns an array of references to the created components.
+
+ // ask foo to create components _bar_ and _zot_, but set the owner of
+ // both components to _this_.
+ this.$.foo.createComponents([
+ {name: "bar"},
+ {name: "zot"}
+ ], {owner: this});
+ */
+ createComponents: function(inInfos, inCommonInfo) {
+ if (inInfos) {
+ var cs = [];
+ for (var i=0, ci; (ci=inInfos[i]); i++) {
+ cs.push(this._createComponent(ci, inCommonInfo));
+ }
+ return cs;
+ }
+ },
+ //* @protected
+ getBubbleTarget: function() {
+ return this.owner;
+ },
+ //* @public
+ /**
+ Bubbles an event up an object chain, starting with _this_.
+
+ If a handler for this event returns true (aka _handled_),
+ bubbling is stopped.
+
+ Handlers always have this signature:
+
+ function(inSender, inEvent)
+
+ where _inSender_ refers to the Component that most recently
+ propagated the event and _inEvent_ is an object containing
+ event information.
+
+ _inEvent_ will have at least one property, _originator_, which
+ references the component that triggered the event in the first place.
+ */
+ bubble: function(inEventName, inEvent, inSender) {
+ var e = inEvent || {};
+ // FIXME: is this the right place?
+ if (!("originator" in e)) {
+ e.originator = inSender || this;
+ // FIXME: use indirection here?
+ //e.delegate = e.originator.delegate || e.originator.owner;
+ }
+ return this.dispatchBubble(inEventName, e, inSender);
+ },
+ /**
+ Bubbles an event up an object chain, starting <b>above</b> _this_.
+
+ If a handler for this event returns true (aka _handled_),
+ bubbling is stopped.
+
+ Handlers always have this signature:
+
+ function(inSender, inEvent)
+
+ where _inSender_ refers to the Component that most recently
+ propagated the event and _inEvent_ is an object containing
+ event information.
+
+ _inEvent_ will have at least one property, _originator_, which
+ references the component that triggered the event in the first place.
+ */
+ bubbleUp: function(inEventName, inEvent, inSender) {
+ // Bubble to next target
+ var next = this.getBubbleTarget();
+ if (next) {
+ return next.dispatchBubble(inEventName, inEvent, this);
+ }
+ return false;
+ },
+ //* @protected
+ /**
+ Dispatching refers to sending an event to a named delegate.
+ This object may dispatch an event to itself via a handler,
+ or to its owner via an event property, e.g.:
+
+ handlers {
+ // 'tap' events dispatched to this.tapHandler
+ ontap: "tapHandler"
+ }
+
+ // 'tap' events dispatched to 'tapHandler' delegate in this.owner
+ ontap: "tapHandler"
+ */
+ dispatchEvent: function(inEventName, inEvent, inSender) {
+ // bottleneck event decoration
+ this.decorateEvent(inEventName, inEvent, inSender);
+ //
+ // Note: null checks and sub-expressions are unrolled in this
+ // high frequency method to reduce call stack in the 90% case.
+ // These expressions should fail early.
+ //
+ // try to dispatch this event directly via handlers
+ //
+ if (this.handlers[inEventName] && this.dispatch(this.handlers[inEventName], inEvent, inSender)) {
+ return true;
+ }
+ //
+ // try to delegate this event to our owner via event properties
+ //
+ if (this[inEventName]) {
+ return this.bubbleDelegation(this.owner, this[inEventName], inEventName, inEvent, this);
+ }
+ },
+ // internal - try dispatching event to self, if that fails bubble it up the tree
+ dispatchBubble: function(inEventName, inEvent, inSender) {
+ // Try to dispatch from here, stop bubbling on truthy return value
+ if (this.dispatchEvent(inEventName, inEvent, inSender)) {
+ return true;
+ }
+ // Bubble to next target
+ return this.bubbleUp(inEventName, inEvent, inSender);
+ },
+ decorateEvent: function(inEventName, inEvent, inSender) {
+ // an event may float by us as part of a dispatchEvent chain or delegateEvent
+ // both call this method so intermediaries can decorate inEvent
+ },
+ bubbleDelegation: function(inDelegate, inName, inEventName, inEvent, inSender) {
+ // next target in bubble sequence
+ var next = this.getBubbleTarget();
+ if (next) {
+ return next.delegateEvent(inDelegate, inName, inEventName, inEvent, inSender);
+ }
+ },
+ delegateEvent: function(inDelegate, inName, inEventName, inEvent, inSender) {
+ // override this method to play tricks with delegation
+ // bottleneck event decoration
+ this.decorateEvent(inEventName, inEvent, inSender);
+ // by default, dispatch this event if we are in fact the delegate
+ if (inDelegate == this) {
+ return this.dispatch(inName, inEvent, inSender);
+ }
+ return this.bubbleDelegation(inDelegate, inName, inEventName, inEvent, inSender);
+ },
+ //* @public
+ /**
+ Dispatches the event to named delegate _inMethodName_, if it exists.
+ Subkinds may re-route dispatches.
+ Note that both 'handlers' events and events delegated from owned controls
+ arrive here. If you need to handle these differently, you may
+ need to also override _dispatchEvent_.
+ */
+ dispatch: function(inMethodName, inEvent, inSender) {
+ var fn = inMethodName && this[inMethodName];
+ if (fn) {
+ return fn.call(this, inSender || this, inEvent);
+ }
+ },
+ /**
+ Sends a message to myself and all of my components.
+ You can stop a waterfall into components owned by a
+ receiving object by returning a truthy value from
+ the event handler.
+ */
+ waterfall: function(inMessageName, inMessage, inSender) {
+ //this.log(inMessageName, (inSender || this).name, "=>", this.name);
+ if (this.dispatchEvent(inMessageName, inMessage, inSender)) {
+ return true;
+ }
+ this.waterfallDown(inMessageName, inMessage, inSender || this);
+ },
+ /**
+ Sends a message to all of my components, but not myself.
+ You can stop a waterfall into components owned by a
+ receiving object by returning a truthy value from
+ the event handler.
+ */
+ waterfallDown: function(inMessageName, inMessage, inSender) {
+ for (var n in this.$) {
+ this.$[n].waterfall(inMessageName, inMessage, inSender);
+ }
+ }
+});
+
+//* @protected
+
+enyo.defaultCtor = enyo.Component;
+
+// a method to create new instances from config objects. It handles looking up the proper
+// constructor based on the provided kind attribute.
+enyo.create = enyo.Component.create = function(inConfig) {
+ if (!inConfig.kind && ("kind" in inConfig)) {
+ throw "enyo.create: Attempt to create a null kind. Check dependencies for [" + (inConfig.name || "") + "].";
+ }
+ var kind = inConfig.kind || inConfig.isa || enyo.defaultCtor;
+ var ctor = enyo.constructorForKind(kind);
+ if (!ctor) {
+ enyo.error('no constructor found for kind "' + kind + '"');
+ ctor = enyo.Component;
+ }
+ return new ctor(inConfig);
+};
+
+enyo.Component.subclass = function(ctor, props) {
+ // Note: to reduce API surface area, sub-components are declared only as
+ // 'components' in both kind and instance declarations.
+ //
+ // However, 'components' from kind declarations must be handled separately
+ // at create-time.
+ //
+ // We rename the property here to avoid having
+ // to interrogate the prototype at create-time.
+ //
+ var proto = ctor.prototype;
+ //
+ if (props.components) {
+ proto.kindComponents = props.components;
+ delete proto.components;
+ }
+ //
+ // handlers are merged with supertype handlers
+ // and kind time.
+ //
+ if (props.handlers) {
+ var kh = proto.kindHandlers;
+ proto.kindHandlers = enyo.mixin(enyo.clone(kh), proto.handlers);
+ proto.handlers = null;
+ }
+ // events property defines published events for Component kinds
+ if (props.events) {
+ this.publishEvents(ctor, props);
+ }
+};
+
+enyo.Component.publishEvents = function(ctor, props) {
+ var es = props.events;
+ if (es) {
+ var cp = ctor.prototype;
+ for (var n in es) {
+ this.addEvent(n, es[n], cp);
+ }
+ }
+};
+
+enyo.Component.addEvent = function(inName, inValue, inProto) {
+ var v, fn;
+ if (!enyo.isString(inValue)) {
+ v = inValue.value;
+ fn = inValue.caller;
+ } else {
+ if (inName.slice(0, 2) != 'on') {
+ enyo.warn("enyo.Component.addEvent: event names must start with 'on'. " + inProto.kindName +
+ " event '" + inName + "' was auto-corrected to 'on" + inName + "'.");
+ inName = "on" + inName;
+ }
+ v = inValue;
+ fn = "do" + enyo.cap(inName.slice(2));
+ }
+ inProto[inName] = v;
+ if (!inProto[fn]) {
+ inProto[fn] = function(inEvent) {
+ // bubble this event
+ return this.bubble(inName, inEvent);
+ };
+ // NOTE: Mark this function as a generated event handler to allow us to
+ // do event chaining. Is this too complicated?
+ //inProto[fn]._dispatcher = true;
+ }
+};
+
+enyo.Component.prefixFromKindName = function(inKindName) {
+ var prefix = enyo.Component._kindPrefixi[inKindName];
+ if (!prefix) {
+ // memoize naming information for this kind
+ var l = inKindName.lastIndexOf(".");
+ prefix = (l >= 0) ? inKindName.slice(l+1) : inKindName;
+ // lower-case the leading char
+ prefix = prefix.charAt(0).toLowerCase() + prefix.slice(1);
+ // memoize result
+ enyo.Component._kindPrefixi[inKindName] = prefix;
+ }
+ return prefix;
+};
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcekernelLayoutjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/kernel/Layout.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/kernel/Layout.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/kernel/Layout.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+/**
+ _enyo.Layout_ is the base kind for layout kinds. These are used by
+ <a href="#enyo.UiComponent">enyo.UiComponent</a>-based controls to allow for
+ arranging of the children by setting the _layoutKind_ property.
+
+ Derived kinds will usually provide their own _layoutClass_ property to
+ affect the CSS rules used, and may also implement the _flow_ and _reflow_
+ methods. _flow_ is called during control rendering, while _reflow_ is called
+ when the associated control is resized.
+*/
+enyo.kind({
+ name: "enyo.Layout",
+ kind: null,
+ //* CSS class that's added to the control using this layout kind
+ layoutClass: "",
+ //* @protected
+ constructor: function(inContainer) {
+ this.container = inContainer;
+ if (inContainer) {
+ inContainer.addClass(this.layoutClass);
+ }
+ },
+ destroy: function() {
+ if (this.container) {
+ this.container.removeClass(this.layoutClass);
+ }
+ },
+ // static property layout
+ flow: function() {
+ },
+ // dynamic measuring layout
+ reflow: function() {
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcekernelObjectjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/kernel/Object.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/kernel/Object.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/kernel/Object.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,143 @@
</span><ins>+/**
+_enyo.Object_ implements the Enyo framework's property publishing system, as
+well as providing several utility functions for its subkinds.
+
+Published properties are declared in a hash called _published_ within a call
+to _enyo.kind_. Getter and setter methods are automatically generated for
+properties declared in this manner. Also, by convention, the setter for a
+published property will trigger an optional _<propertyName>Changed_ method
+when called.
+
+For more information, see the [documentation on Published
+Properties](https://github.com/enyojs/enyo/wiki/Published-Properties) in the
+Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.Object",
+ //* @protected
+ // has no base kind
+ kind: null,
+ constructor: function() {
+ enyo._objectCount++;
+ },
+ /**
+ Sets property named 'n' with value 'v' and then invokes callback
+ function 'cf' (if specified), passing in the original value of 'n'.
+ All property setting should bottleneck here so that objects can
+ observe changes wlog.
+ */
+ setPropertyValue: function(n, v, cf) {
+ if (this[cf]) {
+ var old = this[n];
+ this[n] = v;
+ this[cf](old);
+ } else {
+ this[n] = v;
+ }
+ },
+ _setProperty: function(n, v, cf) {
+ this.setPropertyValue(n, v, (this.getProperty(n) !== v) && cf);
+ },
+ //* @public
+ //* Destroys object with passed-in name.
+ destroyObject: function(inName) {
+ if (this[inName] && this[inName].destroy) {
+ this[inName].destroy();
+ }
+ this[inName] = null;
+ },
+ //* Gets value of property with passed-in name.
+ getProperty: function(n) {
+ var getter = "get" + enyo.cap(n);
+ if (this[getter]) {
+ return this[getter]();
+ }
+ return this[n];
+ },
+ //* Sets value of property named 'n' to 'v'.
+ setProperty: function(n, v) {
+ var setter = "set" + enyo.cap(n);
+ if (this[setter]) {
+ this[setter](v);
+ } else {
+ this._setProperty(n, v, n + "Changed");
+ }
+ },
+ /**
+ Sends a log message to the console, prepended with the name of the kind
+ and method from which _log_ was invoked. Multiple arguments are coerced
+ to String and joined with spaces.
+
+ enyo.kind({
+ name: "MyObject",
+ kind: enyo.Object,
+ hello: function() {
+ this.log("says", "hi");
+ // shows in the console: MyObject.hello: says hi
+ }
+ });
+ */
+ log: function() {
+ var acc = arguments.callee.caller;
+ var nom = ((acc ? acc.nom : "") || "(instance method)") + ":";
+ enyo.logging.log("log", [nom].concat(enyo.cloneArray(arguments)));
+ },
+ //* Same as _log_, except uses the console's warn method (if it exists).
+ warn: function() {
+ this._log("warn", arguments);
+ },
+ //* Same as _log_, except uses the console's error method (if it exists).
+ error: function() {
+ this._log("error", arguments);
+ },
+ //* @protected
+ _log: function(inMethod, inArgs) {
+ if (enyo.logging.shouldLog(inMethod)) {
+ try {
+ throw new Error();
+ } catch(x) {
+ enyo.logging._log(inMethod, [inArgs.callee.caller.nom + ": "].concat(enyo.cloneArray(inArgs)));
+ enyo.log(x.stack);
+ }
+ }
+ }
+});
+
+//* @protected
+
+enyo._objectCount = 0;
+
+enyo.Object.subclass = function(ctor, props) {
+ this.publish(ctor, props);
+};
+
+enyo.Object.publish = function(ctor, props) {
+ var pp = props.published;
+ if (pp) {
+ var cp = ctor.prototype;
+ for (var n in pp) {
+ enyo.Object.addGetterSetter(n, pp[n], cp);
+ }
+ }
+};
+
+enyo.Object.addGetterSetter = function(inName, inValue, inProto) {
+ var priv_n = inName;
+ inProto[priv_n] = inValue;
+ //
+ var cap_n = enyo.cap(priv_n);
+ var get_n = "get" + cap_n;
+ if (!inProto[get_n]) {
+ inProto[get_n] = function() {
+ return this[priv_n];
+ };
+ }
+ //
+ var set_n = "set" + cap_n;
+ var change_n = priv_n + "Changed";
+ if (!inProto[set_n]) {
+ inProto[set_n] = function(v) {
+ this._setProperty(priv_n, v, change_n);
+ };
+ }
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcekernelOopjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/kernel/Oop.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/kernel/Oop.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/kernel/Oop.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,218 @@
</span><ins>+//* @public
+/**
+ Creates a JavaScript constructor function with a prototype defined by
+ _inProps_.
+
+ _enyo.kind_ makes it easy to build a constructor-with-prototype (like a
+ class) that has advanced features like prototype-chaining (inheritance).
+
+ A plug-in system is included for extending the abilities of the kind
+ generator, and constructors are allowed to perform custom operations when
+ subclassed.
+
+ If you make changes to _enyo.kind_, be sure to add or update the appropriate
+ [unit tests](https://github.com/enyojs/enyo/tree/master/tools/test/core/tests).
+
+ For more information, see the documentation on
+ [Creating Kinds](https://github.com/enyojs/enyo/wiki/Creating-Kinds)
+ in the Enyo Developer Guide.
+*/
+enyo.kind = function(inProps) {
+ // kind-name to constructor map could be faulty now that a new kind exists, so we simply destroy the memoizations
+ enyo._kindCtors = {};
+ // extract 'name' property
+ var name = inProps.name || "";
+ delete inProps.name;
+ // extract 'kind' property
+ var hasKind = ("kind" in inProps);
+ var kind = inProps.kind;
+ delete inProps.kind;
+ // establish base class reference
+ var base = enyo.constructorForKind(kind);
+ var isa = base && base.prototype || null;
+ // if we have an explicit kind property with value undefined, we probably
+ // tried to reference a kind that is not yet in scope
+ if (hasKind && kind === undefined || base === undefined) {
+ var problem = kind === undefined ? 'undefined kind' : 'unknown kind (' + kind + ')';
+ throw "enyo.kind: Attempt to subclass an " + problem + ". Check dependencies for [" + (name || "<unnamed>") + "].";
+ }
+ // make a boilerplate constructor
+ var ctor = enyo.kind.makeCtor();
+ // semi-reserved word 'constructor' causes problems with Prototype and IE, so we rename it here
+ if (inProps.hasOwnProperty("constructor")) {
+ inProps._constructor = inProps.constructor;
+ delete inProps.constructor;
+ }
+ // create our prototype
+ //ctor.prototype = isa ? enyo.delegate(isa) : {};
+ enyo.setPrototype(ctor, isa ? enyo.delegate(isa) : {});
+ // put in our props
+ enyo.mixin(ctor.prototype, inProps);
+ // alias class name as 'kind' in the prototype
+ ctor.prototype.kindName = name;
+ // cache superclass constructor
+ ctor.prototype.base = base;
+ // reference our real constructor
+ ctor.prototype.ctor = ctor;
+ // support pluggable 'features'
+ enyo.forEach(enyo.kind.features, function(fn){ fn(ctor, inProps); });
+ // put reference into namespace
+ enyo.setObject(name, ctor);
+ return ctor;
+};
+
+/**
+ Creates a Singleton
+
+ enyo.singleton({
+ kind: Control,
+ name: "app.MySingleton",
+ published: {
+ value: "foo"
+ },
+ makeSomething: function() {
+ //...
+ }
+ });
+
+ app.MySingleton.makeSomething();
+ app.MySingleton.setValue("bar");
+*/
+enyo.singleton = function(conf, context) {
+ // extract 'name' property (the name of our singleton)
+ var name = conf.name;
+ delete(conf.name);
+ // create an unnamed kind and save its constructor's function
+ var kind = enyo.kind(conf);
+ // create the singleton with the previous name and constructor
+ enyo.setObject(name, new kind(), context);
+};
+
+//* @protected
+enyo.kind.makeCtor = function() {
+ return function() {
+ if (!(this instanceof arguments.callee)) {
+ throw "enyo.kind: constructor called directly, not using 'new'";
+ }
+
+ // two-pass instantiation
+ var result;
+ if (this._constructor) {
+ // pure construction
+ result = this._constructor.apply(this, arguments);
+ }
+ // defer initialization until entire constructor chain has finished
+ if (this.constructed) {
+ // post-constructor initialization
+ this.constructed.apply(this, arguments);
+ }
+ if (result) {
+ return result;
+ }
+ };
+};
+
+// classes referenced by name can omit this namespace (e.g. "Button" instead of "enyo.Button")
+enyo.kind.defaultNamespace = "enyo";
+
+//
+// feature hooks for the oop system
+//
+enyo.kind.features = [];
+
+//
+// 'inherited' feature
+//
+enyo.kind.features.push(function(ctor, props) {
+ var proto = ctor.prototype;
+ if (!proto.inherited) {
+ proto.inherited = enyo.kind.inherited;
+ }
+ if (proto.base) {
+ // decorate function properties to support inherited (do this ex post facto so that
+ // ctor.prototype is known, relies on elements in props being copied by reference)
+ for (var n in props) {
+ var p = props[n];
+ if (enyo.isFunction(p)) {
+ p._inherited = proto.base.prototype[n] || enyo.nop;
+ // FIXME: we used to need some extra values for inherited, then inherited got cleaner
+ // but in the meantime we used these values to support logging in Object.
+ // For now we support this legacy situation, by suppling logging information here.
+ p.nom = proto.kindName + '.' + n + '()';
+ }
+ }
+ }
+});
+
+enyo.kind.inherited = function(args, newArgs) {
+ return args.callee._inherited.apply(this, newArgs || args);
+};
+
+//
+// 'statics' feature
+//
+enyo.kind.features.push(function(ctor, props) {
+ // install common statics
+ enyo.mixin(ctor, enyo.kind.statics);
+ // move props statics to constructor
+ if (props.statics) {
+ enyo.mixin(ctor, props.statics);
+ delete ctor.prototype.statics;
+ }
+ // allow superclass customization
+ var base = ctor.prototype.base;
+ while (base) {
+ base.subclass(ctor, props);
+ base = base.prototype.base;
+ }
+});
+
+enyo.kind.statics = {
+ subclass: function(ctor, props) {
+ //enyo.log("subclassing [" + ctor.prototype.kind + "] from [", this.prototype.kind + "]");
+ },
+ extend: function(props) {
+ enyo.mixin(this.prototype, props);
+ // support pluggable 'features'
+ var ctor = this;
+ enyo.forEach(enyo.kind.features, function(fn){ fn(ctor, props); });
+ }
+};
+
+//
+// factory for kinds identified by strings
+//
+enyo._kindCtors = {};
+
+enyo.constructorForKind = function(inKind) {
+ if (inKind === null || enyo.isFunction(inKind)) {
+ // in inKind is a function or explicitly null, then that's ctor, full stop.
+ return inKind;
+ }
+ if (inKind) {
+ // use memoized constructor if available...
+ var ctor = enyo._kindCtors[inKind];
+ if (ctor) {
+ return ctor;
+ }
+ // otherwise look it up and memoize what we find
+ //
+ // if inKind is an object in enyo, say "Control", then ctor = enyo["Control"]
+ // if inKind is a path under enyo, say "Heritage.Button", then ctor = enyo["Heritage.Button"] || enyo.Heritage.Button
+ // if inKind is a fully qualified path, say "enyo.Heritage.Button", then ctor = enyo["enyo.Heritage.Button"] || enyo.enyo.Heritage.Button || enyo.Heritage.Button
+ //
+ // Note that kind "Foo" will resolve to enyo.Foo before resolving to global "Foo".
+ // This is important so "Image" will map to built-in Image object, instead of enyo.Image control.
+ return enyo._kindCtors[inKind] = enyo.Theme[inKind] || enyo[inKind] || enyo.getObject(inKind, false, enyo) || window[inKind] || enyo.getObject(inKind);
+ }
+ return enyo.defaultCtor;
+};
+
+//
+// namespace for current theme ("enyo.Theme.Button" references the Button specialization for the current theme)
+//
+enyo.Theme = {};
+
+enyo.registerTheme = function(inNamespace) {
+ enyo.mixin(enyo.Theme, inNamespace);
+};
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcekernelSignalsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/kernel/Signals.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/kernel/Signals.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/kernel/Signals.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+/**
+ _enyo.Signals_ components are used to listen to global messages.
+
+ An object with a Signals component can listen to messages sent from anywhere
+ by declaring handlers for them.
+
+ DOM events that have no node targets are broadcast as signals. These events
+ include Window events, like _onload_ and _onbeforeunload_, and events that
+ occur directly on _document_, like _onkeypress_ if _document_ has the focus.
+
+ For more information, see the
+ <a href="https://github.com/enyojs/enyo/wiki/Signals">Signals documentation</a>
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.Signals",
+ kind: enyo.Component,
+ //* @protected
+ create: function() {
+ this.inherited(arguments);
+ enyo.Signals.addListener(this);
+ },
+ destroy: function() {
+ enyo.Signals.removeListener(this);
+ this.inherited(arguments);
+ },
+ notify: function(inMsg, inPayload) {
+ this.dispatchEvent(inMsg, inPayload);
+ },
+ statics: {
+ listeners: [],
+ addListener: function(inListener) {
+ this.listeners.push(inListener);
+ },
+ removeListener: function(inListener) {
+ enyo.remove(inListener, this.listeners);
+ },
+ send: function(inMsg, inPayload) {
+ enyo.forEach(this.listeners, function(l) {
+ l.notify(inMsg, inPayload);
+ });
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcekernelUiComponentjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/kernel/UiComponent.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/kernel/UiComponent.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/kernel/UiComponent.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,316 @@
</span><ins>+/**
+ _enyo.UiComponent_ implements a container strategy suitable for presentation
+ layers.
+
+ UiComponent itself is abstract. Concrete subkinds include
+ <a href="#enyo.Control">enyo.Control</a> (for HTML/DOM) and
+ <a href="#enyo.canvas.Control">enyo.canvas.Control</a>
+ (for Canvas contexts).
+*/
+enyo.kind({
+ name: "enyo.UiComponent",
+ kind: enyo.Component,
+ published: {
+ //* The UiComponent that physically contains this component in the DOM
+ container: null,
+ /**
+ The UiComponent that owns this component for purposes of event
+ propagation
+ */
+ parent: null,
+ /**
+ The UiComponent that will physically contain new items added by
+ calls to _createComponent_
+ */
+ controlParentName: "client",
+ //* A kind used to manage the size and placement of child components
+ layoutKind: ""
+ },
+ handlers: {
+ onresize: "resizeHandler"
+ },
+ /**
+ When set, provides a control reference used to indicate where a
+ newly-created component should be added in the UiComponent's array of
+ children. This is typically used when dynamically creating children
+ (rather than at design time). If set to null, the new control will be
+ added at the beginning of the array; if set to a specific existing
+ control, the new control will be added before the specified control. If
+ left undefined, the default behavior is to add the new control at the
+ end of the array.
+ */
+ addBefore: undefined,
+ //* @protected
+ statics: {
+ _resizeFlags: {showingOnly: true} // don't waterfall these events into hidden controls
+ },
+ create: function() {
+ this.controls = [];
+ this.children = [];
+ this.containerChanged();
+ this.inherited(arguments);
+ this.layoutKindChanged();
+ },
+ destroy: function() {
+ // Destroys all non-chrome controls (regardless of owner).
+ this.destroyClientControls();
+ // Removes us from our container.
+ this.setContainer(null);
+ // Destroys chrome controls owned by this.
+ this.inherited(arguments);
+ },
+ importProps: function(inProps) {
+ this.inherited(arguments);
+ if (!this.owner) {
+ //this.log("registering ownerless control [" + this.kindName + "] with enyo.master");
+ this.owner = enyo.master;
+ }
+ },
+ // As implemented, _controlParentName_ only works to identify an owned
+ // control created via _createComponents_ (i.e., usually in our _components_
+ // block). To attach a _controlParent_ via other means, one must call
+ // _discoverControlParent_ or set _controlParent_ directly.
+ //
+ // We could call _discoverControlParent_ in _addComponent_, but it would
+ // cause a lot of useless checking.
+ createComponents: function() {
+ var results = this.inherited(arguments);
+ this.discoverControlParent();
+ return results;
+ },
+ discoverControlParent: function() {
+ this.controlParent = this.$[this.controlParentName] || this.controlParent;
+ },
+ adjustComponentProps: function(inProps) {
+ // Components we create have us as a container by default.
+ inProps.container = inProps.container || this;
+ this.inherited(arguments);
+ },
+ // containment
+ containerChanged: function(inOldContainer) {
+ if (inOldContainer) {
+ inOldContainer.removeControl(this);
+ }
+ if (this.container) {
+ this.container.addControl(this, this.addBefore);
+ }
+ },
+ // parentage
+ parentChanged: function(inOldParent) {
+ if (inOldParent && inOldParent != this.parent) {
+ inOldParent.removeChild(this);
+ }
+ },
+ //* @public
+ // Note: Oddly, a Control is considered a descendant of itself.
+ isDescendantOf: function(inAncestor) {
+ var p = this;
+ while (p && p!=inAncestor) {
+ p = p.parent;
+ }
+ return inAncestor && (p == inAncestor);
+ },
+ /**
+ Returns all controls.
+ */
+ getControls: function() {
+ return this.controls;
+ },
+ /**
+ Returns all non-chrome controls.
+ */
+ getClientControls: function() {
+ var results = [];
+ for (var i=0, cs=this.controls, c; (c=cs[i]); i++) {
+ if (!c.isChrome) {
+ results.push(c);
+ }
+ }
+ return results;
+ },
+ /**
+ Destroys "client controls", the same set of controls returned by
+ _getClientControls_.
+ */
+ destroyClientControls: function() {
+ var c$ = this.getClientControls();
+ for (var i=0, c; (c=c$[i]); i++) {
+ c.destroy();
+ }
+ },
+ //* @protected
+ addControl: function(inControl, inBefore) {
+ // Called to add an already created control to the object's control list. It is
+ // not used to create controls and should likely not be called directly.
+ // It can be overridden to detect when controls are added.
+ this.controls.push(inControl);
+ // When we add a Control, we also establish a parent.
+ this.addChild(inControl, inBefore);
+ },
+ removeControl: function(inControl) {
+ // Called to remove a control from the object's control list. As with addControl it
+ // can be overridden to detect when controls are removed.
+ // When we remove a Control, we also remove it from its parent.
+ inControl.setParent(null);
+ return enyo.remove(inControl, this.controls);
+ },
+ indexOfControl: function(inControl) {
+ return enyo.indexOf(inControl, this.controls);
+ },
+ indexOfClientControl: function(inControl) {
+ return enyo.indexOf(inControl, this.getClientControls());
+ },
+ indexInContainer: function() {
+ return this.container.indexOfControl(this);
+ },
+ clientIndexInContainer: function() {
+ return this.container.indexOfClientControl(this);
+ },
+ controlAtIndex: function(inIndex) {
+ return this.controls[inIndex];
+ },
+ // children
+ addChild: function(inChild, inBefore) {
+ // if inBefore is undefined, add to the end of the child list.
+ // If it's null, add to front of list, otherwise add before the
+ // specified control.
+ //
+ // allow delegating the child to a different container
+ if (this.controlParent /*&& !inChild.isChrome*/) {
+ // this.controlParent might have a controlParent, and so on; seek the ultimate parent
+ // inBefore is not passed because that control won't be in the controlParent's scope
+ this.controlParent.addChild(inChild);
+ } else {
+ // NOTE: addChild drives setParent.
+ // It's the opposite for setContainer, where containerChanged (in Containable)
+ // drives addControl.
+ // Because of the way 'parent' is derived from 'container', this difference is
+ // helpful for implementing controlParent.
+ // By the same token, since 'parent' is derived from 'container', setParent is
+ // not intended to be called by client code. Therefore, the lack of parallelism
+ // should be private to this implementation.
+ // Set the child's parent property to this
+ inChild.setParent(this);
+ // track in children array
+ if (inBefore !== undefined) {
+ var idx = (inBefore === null) ? 0 : this.indexOfChild(inBefore);
+ this.children.splice(idx, 0, inChild);
+ } else {
+ this.children.push(inChild);
+ }
+ }
+ },
+ removeChild: function(inChild) {
+ return enyo.remove(inChild, this.children);
+ },
+ indexOfChild: function(inChild) {
+ return enyo.indexOf(inChild, this.children);
+ },
+ layoutKindChanged: function() {
+ if (this.layout) {
+ this.layout.destroy();
+ }
+ this.layout = enyo.createFromKind(this.layoutKind, this);
+ if (this.generated) {
+ this.render();
+ }
+ },
+ flow: function() {
+ if (this.layout) {
+ this.layout.flow();
+ }
+ },
+ // CAVEAT: currently we use the entry point for both
+ // post-render layout work *and* post-resize layout work.
+ reflow: function() {
+ if (this.layout) {
+ this.layout.reflow();
+ }
+ },
+ /**
+ Call after this control has been resized to allow it to process the size change.
+ To respond to a resize, override _resizeHandler_ instead.
+ */
+ // syntactic sugar for 'waterfall("onresize")'
+ resized: function() {
+ this.waterfall("onresize", enyo.UiComponent._resizeFlags);
+ this.waterfall("onpostresize", enyo.UiComponent._resizeFlags);
+ },
+ //* @protected
+ resizeHandler: function() {
+ // FIXME: once we are in the business of reflowing layouts on resize, then we have an
+ // inside/outside problem: some scenarios will need to reflow before child
+ // controls reflow, and some will need to reflow after. Even more complex scenarios
+ // have circular dependencies, and can require multiple passes or other resolution.
+ // When we can rely on CSS to manage reflows we do not have these problems.
+ this.reflow();
+ },
+ /**
+ Sends a message to all my descendents.
+ */
+ waterfallDown: function(inMessage, inPayload, inSender) {
+ // Note: Controls will generally be both in a $ hash and a child list somewhere.
+ // Attempt to avoid duplicated messages by sending only to components that are not
+ // UiComponent, as those components are guaranteed not to be in a child list.
+ // May cause a problem if there is a scenario where a UiComponent owns a pure
+ // Component that in turn owns Controls.
+ //
+ // waterfall to all pure components
+ for (var n in this.$) {
+ if (!(this.$[n] instanceof enyo.UiComponent)) {
+ this.$[n].waterfall(inMessage, inPayload, inSender);
+ }
+ }
+ // waterfall to my children
+ for (var i=0, cs=this.children, c; (c=cs[i]); i++) {
+ // Do not send {showingOnly: true} events to hidden controls. This flag is set for resize events
+ // which are broadcast from within the framework. This saves a *lot* of unnecessary layout.
+ // TODO: Maybe remember that we did this, and re-send those messages on setShowing(true)?
+ // No obvious problems with it as-is, though
+ if (c.showing || !(inPayload && inPayload.showingOnly)) {
+ c.waterfall(inMessage, inPayload, inSender);
+ }
+ }
+ },
+ getBubbleTarget: function() {
+ return this.parent;
+ }
+});
+
+enyo.createFromKind = function(inKind, inParam) {
+ var ctor = inKind && enyo.constructorForKind(inKind);
+ if (ctor) {
+ return new ctor(inParam);
+ }
+};
+
+//
+// Default owner for ownerless UiComponents to allow notifying such UiComponents
+// of important system events like window resize.
+//
+// NOTE: Ownerless UiComponents will not be garbage collected unless explicitly
+// destroyed, as they will be referenced by _enyo.master_.
+//
+enyo.master = new enyo.Component({
+ name: "master",
+ notInstanceOwner: true,
+ eventFlags: {showingOnly: true}, // don't waterfall these events into hidden controls
+ getId: function() {
+ return '';
+ },
+ isDescendantOf: enyo.nop,
+ bubble: function(inEventName, inEvent, inSender) {
+ //enyo.log("master event: " + inEventName);
+ if (inEventName == "onresize") {
+ // Resize is special; waterfall this message.
+ // This works because master is a Component, so it waterfalls
+ // to its owned Components (i.e., master has no children).
+ enyo.master.waterfallDown("onresize", this.eventFlags);
+ enyo.master.waterfallDown("onpostresize", this.eventFlags);
+ } else {
+ // All other top-level events are sent only to interested Signal
+ // receivers.
+ enyo.Signals.send(inEventName, inEvent);
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcekerneljobjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/kernel/job.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/kernel/job.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/kernel/job.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+/**
+ Invokes function _inJob_ after _inWait_ milliseconds have elapsed since the
+ last time _inJobName_ was referenced.
+
+ Jobs can be used to throttle behaviors. If some event may occur once or
+ multiple times, but we want a response to occur only once every _n_ seconds,
+ we can use a job.
+
+ onscroll: function() {
+ // updateThumb will be called, but only when 1s has elapsed since the
+ // last onscroll
+ enyo.job("updateThumb", enyo.bind(this, "updateThumb"), 1000);
+ }
+*/
+enyo.job = function(inJobName, inJob, inWait) {
+ enyo.job.stop(inJobName);
+ enyo.job._jobs[inJobName] = setTimeout(function() {
+ enyo.job.stop(inJobName);
+ inJob();
+ }, inWait);
+};
+
+/**
+ Cancels the named job, if it has not already fired.
+*/
+enyo.job.stop = function(inJobName) {
+ if (enyo.job._jobs[inJobName]) {
+ clearTimeout(enyo.job._jobs[inJobName]);
+ delete enyo.job._jobs[inJobName];
+ }
+};
+
+enyo.job._jobs = {};
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcekernellangjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/kernel/lang.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/kernel/lang.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/kernel/lang.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,416 @@
</span><ins>+(function(){
+ //* @protected
+ enyo.global = this;
+
+ enyo._getProp = function(parts, create, context) {
+ var obj = context || enyo.global;
+ for(var i=0, p; obj && (p=parts[i]); i++){
+ obj = (p in obj ? obj[p] : (create ? obj[p]={} : undefined));
+ }
+ return obj;
+ };
+
+ //* @public
+
+ /**
+ Sets object _name_ to _value_. _name_ may use dot notation, and
+ intermediate objects are created as necessary.
+
+ // set foo.bar.baz to 3; if foo or foo.bar do not exist, they are created
+ enyo.setObject("foo.bar.baz", 3);
+
+ Optionally, _name_ may be relative to object _context_.
+
+ // create foo.zot and set foo.zot.zap to null
+ enyo.setObject("zot.zap", null, foo);
+ */
+ enyo.setObject = function(name, value, context) {
+ var parts=name.split("."), p=parts.pop(), obj=enyo._getProp(parts, true, context);
+ return obj && p ? (obj[p]=value) : undefined;
+ };
+
+ /**
+ Gets object _name_. _name_ may use dot notation. Intermediate objects
+ are created if the _create_ argument is truthy.
+
+ // get the value of foo.bar, or undefined if foo doesn't exist
+ var value = enyo.getObject("foo.bar");
+
+ // get the value of foo.bar; if foo.bar doesn't exist,
+ // it's assigned an empty object, which is then returned
+ var value = enyo.getObject("foo.bar", true);
+
+ Optionally, _name_ may be relative to object _context_.
+
+ // get the value of foo.zot.zap, or undefined if foo.zot doesn't exist
+ var value = enyo.getObject("zot.zap", false, foo);
+ */
+ enyo.getObject = function(name, create, context) {
+ return enyo._getProp(name.split("."), create, context);
+ };
+
+ /**
+ Returns a random Integer between 0 and _inBound_ (0 <= random integer < _inBound_).
+
+ var randomLetter = String.fromCharCode(enyo.irand(26) + 97);
+ */
+ enyo.irand = function(inBound) {
+ return Math.floor(Math.random() * inBound);
+ };
+
+ //* Returns _inString_ with the first letter capitalized.
+ enyo.cap = function(inString) {
+ return inString.slice(0, 1).toUpperCase() + inString.slice(1);
+ };
+
+ //* Returns _inString_ with the first letter un-capitalized.
+ enyo.uncap = function(inString) {
+ return inString.slice(0, 1).toLowerCase() + inString.slice(1);
+ };
+
+ enyo.format = function(inVarArgs) {
+ var pattern = /\%./g;
+ var arg = 0, template = inVarArgs, args = arguments;
+ var replacer = function(inCode) {
+ return args[++arg];
+ };
+ return template.replace(pattern, replacer);
+ };
+
+ var toString = Object.prototype.toString;
+
+ //* Returns true if _it_ is a string.
+ enyo.isString = function(it) {
+ return toString.call(it) === "[object String]";
+ };
+
+ //* Returns true if _it_ is a function.
+ enyo.isFunction = function(it) {
+ return toString.call(it) === "[object Function]";
+ };
+
+ //* Returns true if _it_ is an array.
+ enyo.isArray = Array.isArray || function(it) {
+ return toString.call(it) === "[object Array]";
+ };
+
+ //* Returns true if the argument is true
+ enyo.isTrue = function(it) {
+ return !(it === "false" || it === false || it === 0 || it === null || it === undefined);
+ };
+
+ //* Returns the index of the element in _inArray_ that is equivalent (==) to _inElement_, or -1 if no element is found.
+ enyo.indexOf = function(inElement, inArray, fromIndex) {
+ if (inArray.indexOf) {
+ return inArray.indexOf(inElement, fromIndex);
+ }
+
+ if (fromIndex) {
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+
+ if (fromIndex > inArray.length) {
+ return -1;
+ }
+ }
+
+ for (var i=fromIndex || 0, l=inArray.length, e; (e=inArray[i]) || (i<l); i++) {
+ if (e == inElement) {
+ return i;
+ }
+ }
+ return -1;
+ };
+
+ //* Removes the first element in _inArray_ that is equivalent (==) to _inElement_.
+ enyo.remove = function(inElement, inArray) {
+ var i = enyo.indexOf(inElement, inArray);
+ if (i >= 0) {
+ inArray.splice(i, 1);
+ }
+ };
+
+ /**
+ Invokes _inFunc_ on each element of _inArray_.
+ If _inContext_ is specified, _inFunc_ is called with _inContext_ as _this_.
+ */
+ enyo.forEach = function(inArray, inFunc, inContext) {
+ if (inArray) {
+ var c = inContext || this;
+ if (enyo.isArray(inArray) && inArray.forEach) {
+ inArray.forEach(inFunc, c);
+ } else {
+ var a = Object(inArray);
+ var al = a.length >>> 0;
+ for (var i = 0; i < al; i++) {
+ if (i in a) {
+ inFunc.call(c, a[i], i, a);
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ Invokes _inFunc_ on each element of _inArray_, and returns the results as an Array.
+ If _inContext_ is specified, _inFunc_ is called with _inContext_ as _this_.
+ */
+ enyo.map = function(inArray, inFunc, inContext) {
+ var c = inContext || this;
+ if (enyo.isArray(inArray) && inArray.map) {
+ return inArray.map(inFunc, c);
+ } else {
+ var results = [];
+ var add = function(e, i, a) {
+ results.push(inFunc.call(c, e, i, a));
+ };
+ enyo.forEach(inArray, add, c);
+ return results;
+ }
+ };
+
+ /**
+ Creates a new array with all elements of _inArray_ that pass the test implemented by _inFunc_.
+ If _inContext_ is specified, _inFunc_ is called with _inContext_ as _this_.
+ */
+ enyo.filter = function(inArray, inFunc, inContext) {
+ var c = inContext || this;
+ if (enyo.isArray(inArray) && inArray.filter) {
+ return inArray.filter(inFunc, c);
+ } else {
+ var results = [];
+ var f = function(e, i, a) {
+ var eo = e;
+ if (inFunc.call(c, e, i, a)) {
+ results.push(eo);
+ }
+ };
+ enyo.forEach(inArray, f, c);
+ return results;
+ }
+ };
+
+ /**
+ Returns an array of all own enumerable properties found on _inObject_.
+ */
+ enyo.keys = Object.keys || function(inObject) {
+ var results = [];
+ var hop = Object.prototype.hasOwnProperty;
+ for (var prop in inObject) {
+ if (hop.call(inObject, prop)) {
+ results.push(prop);
+ }
+ }
+ // *sigh* IE 8
+ if (!({toString: null}).propertyIsEnumerable("toString")) {
+ var dontEnums = [
+ 'toString',
+ 'toLocaleString',
+ 'valueOf',
+ 'hasOwnProperty',
+ 'isPrototypeOf',
+ 'propertyIsEnumerable',
+ 'constructor'
+ ];
+ for (var i = 0, p; (p = dontEnums[i]); i++) {
+ if (hop.call(inObject, p)) {
+ results.push(p);
+ }
+ }
+ }
+ return results;
+ };
+
+ /**
+ Clones an existing Array, or converts an array-like object into an Array.
+
+ If _inOffset_ is non-zero, the cloning is started from that index in the source Array.
+ The clone may be appended to an existing Array by passing the existing Array as _inStartWith_.
+
+ Array-like objects have _length_ properties, and support square-bracket notation ([]).
+ Often array-like objects do not support Array methods, such as _push_ or _concat_, and
+ must be converted to Arrays before use.
+
+ The special _arguments_ variable is an example of an array-like object.
+ */
+ enyo.cloneArray = function(inArrayLike, inOffset, inStartWith) {
+ var arr = inStartWith || [];
+ for(var i = inOffset || 0, l = inArrayLike.length; i<l; i++){
+ arr.push(inArrayLike[i]);
+ }
+ return arr;
+ };
+ enyo.toArray = enyo.cloneArray;
+
+ /**
+ Shallow-clones an object or an array.
+ */
+ enyo.clone = function(obj) {
+ return enyo.isArray(obj) ? enyo.cloneArray(obj) : enyo.mixin({}, obj);
+ };
+
+ //* @protected
+ var empty = {};
+
+ //* @public
+ /**
+ Copies custom properties from the _source_ object to the _target_ object.
+ If _target_ is falsey, an object is created.
+ If _source_ is falsey, the target or empty object is returned.
+ */
+ enyo.mixin = function(target, source) {
+ target = target || {};
+ if (source) {
+ var name, s, i;
+ for (name in source) {
+ // the "empty" conditional avoids copying properties in "source"
+ // inherited from Object.prototype. For example, if target has a custom
+ // toString() method, don't overwrite it with the toString() method
+ // that source inherited from Object.prototype
+ s = source[name];
+ if (empty[name] !== s) {
+ target[name] = s;
+ }
+ }
+ }
+ return target;
+ };
+
+ //* @public
+ /**
+ Returns a function closure that will call (and return the value of)
+ function _method_, with _scope_ as _this_.
+
+ _method_ can be a function or the string name of a function-valued
+ property on _scope_.
+
+ Arguments to the closure are passed into the bound function.
+
+ // a function that binds this to this.foo
+ var fn = enyo.bind(this, "foo");
+ // the value of this.foo(3)
+ var value = fn(3);
+
+ Optionally, any number of arguments may be prefixed to the bound function.
+
+ // a function that binds this to this.bar, with arguments ("hello", 42)
+ var fn = enyo.bind(this, "bar", "hello", 42);
+ // the value of this.bar("hello", 42, "goodbye");
+ var value = fn("goodbye");
+
+ Functions may be bound to any scope.
+
+ // binds function 'bar' to scope 'foo'
+ var fn = enyo.bind(foo, bar);
+ // the value of bar.call(foo);
+ var value = fn();
+ */
+ enyo.bind = function(scope, method/*, bound arguments*/){
+ if (!method) {
+ method = scope;
+ scope = null;
+ }
+ scope = scope || enyo.global;
+ if (enyo.isString(method)) {
+ if (scope[method]) {
+ method = scope[method];
+ } else {
+ throw(['enyo.bind: scope["', method, '"] is null (scope="', scope, '")'].join(''));
+ }
+ }
+ if (enyo.isFunction(method)) {
+ var args = enyo.cloneArray(arguments, 2);
+ if (method.bind) {
+ return method.bind.apply(method, [scope].concat(args));
+ } else {
+ return function() {
+ var nargs = enyo.cloneArray(arguments);
+ // invoke with collected args
+ return method.apply(scope, args.concat(nargs));
+ };
+ }
+ } else {
+ throw(['enyo.bind: scope["', method, '"] is not a function (scope="', scope, '")'].join(''));
+ }
+ };
+
+ /**
+ Calls method _inMethod_ on _inScope_ asynchronously.
+
+ Uses _window.setTimeout_ with minimum delay, usually
+ around 10ms.
+
+ Additional arguments are passed to _inMethod_ when
+ it is invoked.
+ */
+ enyo.asyncMethod = function(inScope, inMethod/*, inArgs*/) {
+ return setTimeout(enyo.bind.apply(enyo, arguments), 1);
+ };
+
+ /**
+ Calls named method _inMethod_ (String) on _inObject_ with optional
+ arguments _inArguments_ (Array), if the object and method exist.
+
+ enyo.call(myWorkObject, "doWork", [3, "foo"]);
+ */
+ enyo.call = function(inObject, inMethod, inArguments) {
+ var context = inObject || this;
+ if (inMethod) {
+ var fn = context[inMethod] || inMethod;
+ if (fn && fn.apply) {
+ return fn.apply(context, inArguments || []);
+ }
+ }
+ };
+
+ /**
+ Returns the current time.
+
+ The returned value is equivalent to _new Date().getTime()_.
+ */
+ enyo.now = Date.now || function() {
+ return new Date().getTime();
+ };
+
+ //* @protected
+
+ enyo.nop = function(){};
+ enyo.nob = {};
+ enyo.nar = [];
+
+ // this name is reported in inspectors as the type of objects created via delegate,
+ // otherwise we would just use enyo.nop
+ enyo.instance = function() {};
+
+ // some platforms need alternative syntax (e.g., when compiled as a v8 builtin)
+ if (!enyo.setPrototype) {
+ enyo.setPrototype = function(ctor, proto) {
+ ctor.prototype = proto;
+ };
+ }
+
+ // boodman/crockford delegation w/cornford optimization
+ enyo.delegate = function(obj) {
+ enyo.setPrototype(enyo.instance, obj);
+ return new enyo.instance();
+ };
+
+ //* @public
+
+ /**
+ Provides a stub function for _g11n_ string translation. This allows
+ strings to be wrapped in preparation for localization. If the _g11n_
+ library is not loaded, this function will return the string as is.
+
+ $L('Welcome')
+
+ If the _g11n_ library is loaded, this function will be replaced by the
+ _g11n_ library version, which translates wrapped strings to strings from
+ a developer-provided resource file corresponding to the current user
+ locale.
+ */
+ $L = function(string) {
+ return string;
+ };
+})();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcekernellogjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/kernel/log.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/kernel/log.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/kernel/log.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+//* @protected
+
+enyo.logging = {
+ // log levels are integers from 0-99
+ // 99 is maximum logging
+ level: 99,
+ // set level to -1 to disable all logging
+ levels: {log: 20, warn: 10, error: 0},
+ // return true if logging level is lower than the current log level
+ shouldLog: function(inMethod) {
+ var ll = parseInt(this.levels[inMethod], 0);
+ return (ll <= this.level);
+ },
+ /*
+ formatArgs: function(inMethod, inArgs) {
+ var a$ = [];
+ for (var i=0, l=inArgs.length, a; (a=inArgs[i]) || i<l; i++) {
+ if (String(a) == "[object Object]") {
+ a = enyo.json.stringify(a);
+ }
+ a$.push(a);
+ }
+ return a$;
+ },
+ */
+ _log: function(inMethod, inArgs) {
+ // avoid trying to use console on IE instances where the object hasn't been
+ // created due to the developer tools being unopened
+ if (typeof console === "undefined") {
+ return;
+ }
+ //var a$ = enyo.logging.formatArgs(inMethod, inArgs);
+ var a$ = enyo.isArray(inArgs) ? inArgs : enyo.cloneArray(inArgs);
+ if (enyo.dumbConsole) {
+ // at least in early versions of webos, console.* only accept a single argument
+ a$ = [a$.join(" ")];
+ }
+ var fn = console[inMethod];
+ if (fn && fn.apply) {
+ // some consoles support 'warn', 'info', and so on
+ fn.apply(console, a$);
+ } else if (console.log.apply) {
+ // some consoles support console.log.apply
+ console.log.apply(console, a$);
+ } else {
+ // otherwise, do our own formatting
+ console.log(a$.join(" "));
+ }
+ },
+ log: function(inMethod, inArgs) {
+ if (typeof console !== "undefined") {
+ if (this.shouldLog(inMethod)) {
+ this._log(inMethod, inArgs);
+ }
+ }
+ }
+};
+
+//* @public
+
+/**
+ Sets the log level for this window if the input is a real number.
+
+ The log level is used as a watermark to control the amount of logging.
+ Setting the log level lower will prevent logging functions with a higher
+ level from being executed.
+
+ The default log level is 99. <a href="#enyo.log">enyo.log</a> will output
+ if the level is 20 or above, <a href="#enyo.warn">enyo.warn</a> at 10, and
+ <a href="#enyo.error">enyo.error</a> at 0.
+*/
+enyo.setLogLevel = function(inLevel) {
+ var ll = parseInt(inLevel, 0);
+ if (isFinite(ll)) {
+ enyo.logging.level = ll;
+ }
+};
+
+/**
+ Sends a log message to the console, if the current log level allows for it.
+
+ Objects are converted to JSON automatically.
+
+ Multiple arguments are coerced to String and joined with spaces.
+*/
+enyo.log = function() {
+ enyo.logging.log("log", arguments);
+};
+
+//* Same as _log_, except uses the console's warn method (if it exists).
+enyo.warn = function() {
+ enyo.logging.log("warn", arguments);
+};
+
+//* Same as _log_, except uses the console's error method (if it exists).
+enyo.error = function() {
+ enyo.logging.log("error", arguments);
+};
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcekernelmacroizejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/kernel/macroize.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/kernel/macroize.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/kernel/macroize.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+//* @public
+
+/**
+ Populates a string template with data values.
+
+ Returns a copy of _inText_, with macros defined by _inPattern_ replaced by
+ named values in _inMap_.
+
+ _inPattern_ may be omitted, in which case the default macro pattern is used.
+ The default pattern matches macros of the form
+
+ {$name}
+
+ Example:
+
+ // Returns "My name is Barney."
+ enyo.macroize("My name is {$name}.", {name: "Barney"});
+
+ Dot notation is supported, like so:
+
+ var info = {
+ product_0: {
+ name: "Gizmo"
+ weight: 3
+ }
+ }
+ // Returns "Each Gizmo weighs 3 pounds."
+ enyo.macroize("Each {$product_0.name} weighs {$product_0.weight} pounds.", info);
+*/
+enyo.macroize = function(inText, inMap, inPattern) {
+ var v, working, result = inText, pattern = inPattern || enyo.macroize.pattern;
+ var fn = function(macro, name) {
+ v = enyo.getObject(name, false, inMap);
+ if (v === undefined || v === null) {
+ return "{$" + name + "}";
+ }
+ working = true;
+ return v;
+ };
+ var prevent = 0;
+ do {
+ working = false;
+ result = result.replace(pattern, fn);
+ // if iterating more than 20 times, we assume a recursion (we should probably throw)
+ if (++prevent >= 20) {
+ throw("enyo.macroize: recursion too deep");
+ }
+ } while (working);
+ return result;
+};
+
+/**
+ Similar to _enyo.macroize_, but performs only one iteration of the _replace_
+ call. This means that recursive expansion of macros isn't possible, but it
+ avoids the extra processing needed to find recursive use.
+*/
+enyo.quickMacroize = function(inText, inMap, inPattern) {
+ var v, working, result = inText, pattern = inPattern || enyo.macroize.pattern;
+ var fn = function(macro, name) {
+ if (name in inMap) {
+ v = inMap[name];
+ } else {
+ v = enyo.getObject(name, false, inMap);
+ }
+ return (v === undefined || v === null) ? "{$" + name + "}" : v;
+ };
+ result = result.replace(pattern, fn);
+ return result;
+};
+
+//* @protected
+
+// Matches macros of the form {$name}.
+enyo.macroize.pattern = /\{\$([^{}]*)\}/g;
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcekernelpackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/kernel/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/kernel/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/kernel/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+enyo.depends(
+ "log.js",
+ "lang.js",
+ "job.js",
+ "macroize.js",
+ "Oop.js",
+ "Object.js",
+ "Component.js",
+ "UiComponent.js",
+ "Layout.js",
+ "Signals.js"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcepackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+enyo.depends(
+ "kernel",
+ "ajax",
+ "dom",
+ "touch",
+ "ui"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchScrollMathjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/ScrollMath.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/ScrollMath.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/ScrollMath.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,305 @@
</span><ins>+/**
+_enyo.ScrollMath_ implements a scrolling dynamics simulation. It is a helper
+kind used by other scroller kinds, such as
+<a href="#enyo.TouchScrollStrategy">enyo.TouchScrollStrategy</a>.
+
+_enyo.ScrollMath_ is not typically created in application code.
+*/
+enyo.kind({
+ name: "enyo.ScrollMath",
+ kind: enyo.Component,
+ published: {
+ //* True if vertical scrolling is enabled
+ vertical: true,
+ //* True if horizontal scrolling is enabled
+ horizontal: true
+ },
+ events: {
+ //* Fires when scroll action starts.
+ onScrollStart: "",
+ //* Fires while scroll action is in progress.
+ onScroll: "",
+ //* Fires when scroll action stops.
+ onScrollStop: ""
+ },
+ //* 'Spring' damping returns the scroll position to a value inside the
+ //* boundaries. Lower values provide _faster_ snapback.
+ kSpringDamping: 0.93,
+ //* 'Drag' damping resists dragging the scroll position beyond the
+ //* boundaries. Lower values provide _more_ resistance.
+ kDragDamping: 0.5,
+ //* 'Friction' damping reduces momentum over time. Lower values provide
+ //* _more_ friction.
+ kFrictionDamping: 0.97,
+ //* Additional 'friction' damping applied when momentum carries the viewport
+ //* into overscroll. Lower values provide _more_ friction.
+ kSnapFriction: 0.9,
+ //* Scalar applied to 'flick' event velocity
+ kFlickScalar: 15,
+ //* Limits the maximum allowable flick. On Android > 2, we limit this to
+ //* prevent compositing artifacts.
+ kMaxFlick: enyo.platform.android > 2 ? 2 : 1e9,
+ //* The value used in friction() to determine if the delta (e.g., y - y0) is
+ //* close enough to zero to consider as zero
+ kFrictionEpsilon: 1e-2,
+ //* Top snap boundary, generally 0
+ topBoundary: 0,
+ //* Right snap boundary, generally (viewport width - content width)
+ rightBoundary: 0,
+ //* Bottom snap boundary, generally (viewport height - content height)
+ bottomBoundary: 0,
+ //* Left snap boundary, generally 0
+ leftBoundary: 0,
+ //* Animation time step
+ interval: 20,
+ //* Flag to enable frame-based animation; if false, time-based animation is used
+ fixedTime: true,
+ //* @protected
+ // simulation state
+ x0: 0,
+ x: 0,
+ y0: 0,
+ y: 0,
+ destroy: function() {
+ this.stop();
+ this.inherited(arguments);
+ },
+ /**
+ Simple Verlet integrator for simulating Newtonian motion.
+ */
+ verlet: function(p) {
+ var x = this.x;
+ this.x += x - this.x0;
+ this.x0 = x;
+ //
+ var y = this.y;
+ this.y += y - this.y0;
+ this.y0 = y;
+ },
+ /**
+ Boundary damping function.
+ Returns damped 'value' based on 'coeff' on one side of 'origin'.
+ */
+ damping: function(value, origin, coeff, sign) {
+ var kEpsilon = 0.5;
+ //
+ // this is basically just value *= coeff (generally, coeff < 1)
+ //
+ // 'sign' and the conditional is to force the damping to only occur
+ // on one side of the origin.
+ //
+ var dv = value - origin;
+ // Force close-to-zero to zero
+ if (Math.abs(dv) < kEpsilon) {
+ return origin;
+ }
+ return value*sign > origin*sign ? coeff * dv + origin : value;
+ },
+ /**
+ Dual-boundary damping function.
+ Returns damped 'value' based on 'coeff' when exceeding either boundary.
+ */
+ boundaryDamping: function(value, aBoundary, bBoundary, coeff) {
+ return this.damping(this.damping(value, aBoundary, coeff, 1), bBoundary, coeff, -1);
+ },
+ /**
+ Simulation constraints (spring damping occurs here)
+ */
+ constrain: function() {
+ var y = this.boundaryDamping(this.y, this.topBoundary, this.bottomBoundary, this.kSpringDamping);
+ if (y != this.y) {
+ // ensure snapping introduces no velocity, add additional friction
+ this.y0 = y - (this.y - this.y0) * this.kSnapFriction;
+ this.y = y;
+ }
+ var x = this.boundaryDamping(this.x, this.leftBoundary, this.rightBoundary, this.kSpringDamping);
+ if (x != this.x) {
+ this.x0 = x - (this.x - this.x0) * this.kSnapFriction;
+ this.x = x;
+ }
+ },
+ /**
+ The friction function
+ */
+ friction: function(inEx, inEx0, inCoeff) {
+ // implicit velocity
+ var dp = this[inEx] - this[inEx0];
+ // let close-to-zero collapse to zero (i.e. smaller than epsilon is considered zero)
+ var c = Math.abs(dp) > this.kFrictionEpsilon ? inCoeff : 0;
+ // reposition using damped velocity
+ this[inEx] = this[inEx0] + c * dp;
+ },
+ // one unit of time for simulation
+ frame: 10,
+ // piece-wise constraint simulation
+ simulate: function(t) {
+ while (t >= this.frame) {
+ t -= this.frame;
+ if (!this.dragging) {
+ this.constrain();
+ }
+ this.verlet();
+ this.friction('y', 'y0', this.kFrictionDamping);
+ this.friction('x', 'x0', this.kFrictionDamping);
+ }
+ return t;
+ },
+ animate: function() {
+ this.stop();
+ // time tracking
+ var t0 = enyo.now(), t = 0;
+ // delta tracking
+ var x0, y0;
+ // animation handler
+ var fn = enyo.bind(this, function() {
+ // wall-clock time
+ var t1 = enyo.now();
+ // schedule next frame
+ this.job = enyo.requestAnimationFrame(fn);
+ // delta from last wall clock time
+ var dt = t1 - t0;
+ // record the time for next delta
+ t0 = t1;
+ // user drags override animation
+ if (this.dragging) {
+ this.y0 = this.y = this.uy;
+ this.x0 = this.x = this.ux;
+ }
+ // frame-time accumulator
+ // min acceptable time is 16ms (60fps)
+ t += Math.max(16, dt);
+ // alternate fixed-time step strategy:
+ if (this.fixedTime && !this.isInOverScroll()) {
+ t = this.interval;
+ }
+ // consume some t in simulation
+ t = this.simulate(t);
+ // scroll if we have moved, otherwise the animation is stalled and we can stop
+ if (y0 != this.y || x0 != this.x) {
+ //this.log(this.y, y0);
+ this.scroll();
+ } else if (!this.dragging) {
+ this.stop(true);
+ this.scroll();
+ }
+ y0 = this.y;
+ x0 = this.x;
+ });
+ this.job = enyo.requestAnimationFrame(fn);
+ },
+ //* @protected
+ start: function() {
+ if (!this.job) {
+ this.animate();
+ this.doScrollStart();
+ }
+ },
+ stop: function(inFireEvent) {
+ this.job = enyo.cancelRequestAnimationFrame(this.job);
+ if (inFireEvent) {
+ this.doScrollStop();
+ }
+ },
+ stabilize: function() {
+ this.start();
+ var y = Math.min(this.topBoundary, Math.max(this.bottomBoundary, this.y));
+ var x = Math.min(this.leftBoundary, Math.max(this.rightBoundary, this.x));
+ this.y = this.y0 = y;
+ this.x = this.x0 = x;
+ this.scroll();
+ this.stop(true);
+ },
+ startDrag: function(e) {
+ this.dragging = true;
+ //
+ this.my = e.pageY;
+ this.py = this.uy = this.y;
+ //
+ this.mx = e.pageX;
+ this.px = this.ux = this.x;
+ },
+ drag: function(e) {
+ if (this.dragging) {
+ var dy = this.vertical ? e.pageY - this.my : 0;
+ this.uy = dy + this.py;
+ // provides resistance against dragging into overscroll
+ this.uy = this.boundaryDamping(this.uy, this.topBoundary, this.bottomBoundary, this.kDragDamping);
+ //
+ var dx = this.horizontal ? e.pageX - this.mx : 0;
+ this.ux = dx + this.px;
+ // provides resistance against dragging into overscroll
+ this.ux = this.boundaryDamping(this.ux, this.leftBoundary, this.rightBoundary, this.kDragDamping);
+ //
+ this.start();
+ return true;
+ }
+ },
+ dragDrop: function(e) {
+ if (this.dragging && !window.PalmSystem) {
+ var kSimulatedFlickScalar = 0.5;
+ this.y = this.uy;
+ this.y0 = this.y - (this.y - this.y0) * kSimulatedFlickScalar;
+ this.x = this.ux;
+ this.x0 = this.x - (this.x - this.x0) * kSimulatedFlickScalar;
+ }
+ this.dragFinish();
+ },
+ dragFinish: function() {
+ this.dragging = false;
+ },
+ flick: function(e) {
+ var v;
+ if (this.vertical) {
+ v = e.yVelocity > 0 ? Math.min(this.kMaxFlick, e.yVelocity) : Math.max(-this.kMaxFlick, e.yVelocity);
+ this.y = this.y0 + v * this.kFlickScalar;
+ }
+ if (this.horizontal) {
+ v = e.xVelocity > 0 ? Math.min(this.kMaxFlick, e.xVelocity) : Math.max(-this.kMaxFlick, e.xVelocity);
+ this.x = this.x0 + v * this.kFlickScalar;
+ }
+ this.start();
+ },
+ mousewheel: function(e) {
+ var dy = this.vertical ? e.wheelDeltaY || e.wheelDelta: 0;
+ if ((dy > 0 && this.y < this.topBoundary) || (dy < 0 && this.y > this.bottomBoundary)) {
+ this.stop(true);
+ this.y = this.y0 = this.y0 + dy;
+ this.start();
+ return true;
+ }
+ },
+ scroll: function() {
+ this.doScroll();
+ },
+ // NOTE: Yip/Orvell method for determining scroller instantaneous velocity
+ // FIXME: incorrect if called when scroller is in overscroll region
+ // because does not account for additional overscroll damping.
+ /**
+ Animates a scroll to the specified position.
+ */
+ scrollTo: function(inX, inY) {
+ if (inY !== null) {
+ this.y = this.y0 - (inY + this.y0) * (1 - this.kFrictionDamping);
+ }
+ if (inX !== null) {
+ this.x = this.x0 - (inX + this.x0) * (1 - this.kFrictionDamping);
+ }
+ this.start();
+ },
+ setScrollX: function(inX) {
+ this.x = this.x0 = inX;
+ },
+ setScrollY: function(inY) {
+ this.y = this.y0 = inY;
+ },
+ setScrollPosition: function(inPosition) {
+ this.setScrollY(inPosition);
+ },
+ isScrolling: function() {
+ return Boolean(this.job);
+ },
+ isInOverScroll: function() {
+ return this.job && (this.x > this.leftBoundary || this.x < this.rightBoundary ||
+ this.y > this.topBoundary || this.y < this.bottomBoundary);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchScrollStrategyjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/ScrollStrategy.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/ScrollStrategy.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/ScrollStrategy.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,186 @@
</span><ins>+/**
+ _enyo.ScrollStrategy_ is a helper kind that implements a default scrolling
+ strategy for an <a href="#enyo.Scroller">enyo.Scroller</a>.
+
+ _enyo.ScrollStrategy_ is not typically created in application code.
+ Instead, it is specified as the value of the `strategyKind` property of an
+ `enyo.Scroller` or <a href="#enyo.List">enyo.List</a>, or is used by the
+ framework implicitly.
+*/
+enyo.kind({
+ name: "enyo.ScrollStrategy",
+ tag: null,
+ published: {
+ /**
+ Specifies how to vertically scroll. Acceptable values are:
+
+ * "scroll": Always shows a scrollbar; sets _overflow: scroll_.
+ * "auto": Scrolls only if needed; sets _overflow: auto_.
+ * "hidden": Never scrolls; sets _overflow: hidden_.
+ * "default": Same as "auto".
+ */
+ vertical: "default",
+ /**
+ Specifies how to horizontally scroll. Acceptable values are:
+
+ * "scroll": Always shows a scrollbar; sets _overflow: scroll_.
+ * "auto": Scrolls only if needed; sets _overflow: auto_.
+ * "hidden": Never scrolls; sets _overflow: hidden_.
+ * "default": Same as "auto".
+ */
+ horizontal: "default",
+ //* Scroll position along horizontal axis
+ scrollLeft: 0,
+ //* Scroll position along vertical axis
+ scrollTop: 0,
+ //* Maximum height of scroll content
+ maxHeight: null
+ },
+ //* @protected
+ handlers: {
+ ondragstart: "dragstart",
+ ondragfinish: "dragfinish",
+ ondown: "down",
+ onmove: "move"
+ },
+ create: function() {
+ this.inherited(arguments);
+ this.horizontalChanged();
+ this.verticalChanged();
+ this.maxHeightChanged();
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ enyo.makeBubble(this.container, "scroll");
+ this.scrollNode = this.calcScrollNode();
+ },
+ teardownRender: function() {
+ this.inherited(arguments);
+ this.scrollNode = null;
+ },
+ calcScrollNode: function() {
+ return this.container.hasNode();
+ },
+ horizontalChanged: function() {
+ this.container.applyStyle("overflow-x", this.horizontal == "default" ? "auto" : this.horizontal);
+ },
+ verticalChanged: function() {
+ this.container.applyStyle("overflow-y", this.vertical == "default" ? "auto" : this.vertical);
+ },
+ maxHeightChanged: function() {
+ this.container.applyStyle("max-height", this.maxHeight);
+ },
+ scrollTo: function(inX, inY) {
+ if (this.scrollNode) {
+ this.setScrollLeft(inX);
+ this.setScrollTop(inY);
+ }
+ },
+ scrollToNode: function(inNode, inAlignWithTop) {
+ if (this.scrollNode) {
+ var sb = this.getScrollBounds();
+ var n = inNode;
+ var b = {height: n.offsetHeight, width: n.offsetWidth, top: 0, left: 0};
+ while (n && n.parentNode && n.id != this.scrollNode.id) {
+ b.top += n.offsetTop;
+ b.left += n.offsetLeft;
+ n = n.parentNode;
+ }
+ // By default, the element is scrolled to align with the top of the scroll area.
+ this.setScrollTop(Math.min(sb.maxTop, inAlignWithTop === false ? b.top - sb.clientHeight + b.height : b.top));
+ this.setScrollLeft(Math.min(sb.maxLeft, inAlignWithTop === false ? b.left - sb.clientWidth + b.width : b.left));
+ }
+ },
+ scrollIntoView: function(inControl, inAlignWithTop) {
+ if (inControl.hasNode()) {
+ inControl.node.scrollIntoView(inAlignWithTop);
+ }
+ },
+ isInView: function(inNode) {
+ var sb = this.getScrollBounds();
+ var ot = inNode.offsetTop;
+ var oh = inNode.offsetHeight;
+ var ol = inNode.offsetLeft;
+ var ow = inNode.offsetWidth;
+ return (ot >= sb.top && ot + oh <= sb.top + sb.clientHeight) && (ol >= sb.left && ol + ow <= sb.left + sb.clientWidth);
+ },
+ setScrollTop: function(inTop) {
+ this.scrollTop = inTop;
+ if (this.scrollNode) {
+ this.scrollNode.scrollTop = this.scrollTop;
+ }
+ },
+ setScrollLeft: function(inLeft) {
+ this.scrollLeft = inLeft;
+ if (this.scrollNode) {
+ this.scrollNode.scrollLeft = this.scrollLeft;
+ }
+ },
+ getScrollLeft: function() {
+ return this.scrollNode ? this.scrollNode.scrollLeft : this.scrollLeft;
+ },
+ getScrollTop: function() {
+ return this.scrollNode ? this.scrollNode.scrollTop : this.scrollTop;
+ },
+ _getScrollBounds: function() {
+ var s = this.getScrollSize(), cn = this.container.hasNode();
+ var b = {
+ left: this.getScrollLeft(),
+ top: this.getScrollTop(),
+ clientHeight: cn ? cn.clientHeight : 0,
+ clientWidth: cn ? cn.clientWidth : 0,
+ height: s.height,
+ width: s.width
+ };
+ b.maxLeft = Math.max(0, b.width - b.clientWidth);
+ b.maxTop = Math.max(0, b.height - b.clientHeight);
+ return b;
+ },
+ getScrollSize: function() {
+ var n = this.scrollNode;
+ return {width: n ? n.scrollWidth : 0, height: n ? n.scrollHeight : 0};
+ },
+ getScrollBounds: function() {
+ return this._getScrollBounds();
+ },
+ calcStartInfo: function() {
+ var sb = this.getScrollBounds();
+ var y = this.getScrollTop(), x = this.getScrollLeft();
+ this.canVertical = sb.maxTop > 0 && this.vertical != "hidden";
+ this.canHorizontal = sb.maxLeft > 0 && this.horizontal != "hidden";
+ this.startEdges = {
+ top: y === 0,
+ bottom: y === sb.maxTop,
+ left: x === 0,
+ right: x === sb.maxLeft
+ };
+ },
+ // NOTE: down, move, and drag handlers are needed only for native touch scrollers
+ shouldDrag: function(inEvent) {
+ var requestV = inEvent.vertical;
+ return (requestV && this.canVertical || !requestV && this.canHorizontal) /*&& !this.isOobVerticalScroll(inEvent)*/;
+ },
+ dragstart: function(inSender, inEvent) {
+ this.dragging = this.shouldDrag(inEvent);
+ if (this.dragging) {
+ return this.preventDragPropagation;
+ }
+ },
+ dragfinish: function(inSender, inEvent) {
+ if (this.dragging) {
+ this.dragging = false;
+ inEvent.preventTap();
+ }
+ },
+ // avoid allowing scroll when starting at a vertical boundary to prevent ios from window scrolling.
+ down: function(inSender, inEvent) {
+ this.calcStartInfo();
+ },
+ // NOTE: mobile native scrollers need touchmove. Indicate this by
+ // setting the requireTouchmove property to true.
+ move: function(inSender, inEvent) {
+ if (inEvent.which && (this.canVertical && inEvent.vertical || this.canHorizontal && inEvent.horizontal)) {
+ inEvent.disablePrevention();
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchScrollercss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/Scroller.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/Scroller.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/Scroller.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+.enyo-scroller {
+ position: relative;
+}
+
+.enyo-fit.enyo-scroller {
+ position: absolute;
+}
+
+.enyo-touch-scroller {
+ overflow: hidden;
+}
+
+.enyo-touch-strategy-container {
+ overflow: hidden;
+}
+
+.enyo-scrollee-fit {
+ height: 100%;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchScrollerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/Scroller.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/Scroller.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/Scroller.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,344 @@
</span><ins>+/**
+_enyo.Scroller_ is a scroller suitable for use in both desktop and mobile
+applications.
+
+In some mobile environments, a default scrolling solution is not implemented for
+DOM elements. In such cases, _enyo.Scroller_ implements a touch-based scrolling
+solution, which may be opted into either globally (by setting the flag
+_enyo.Scroller.touchScrolling = true;_) or on a per-instance basis (by
+specifying a _strategyKind_ of "TouchScrollStrategy").
+
+For more information, see the documentation on
+[Scrollers](https://github.com/enyojs/enyo/wiki/Scrollers) in the Enyo Developer
+Guide.
+*/
+enyo.kind({
+ name: "enyo.Scroller",
+ published: {
+ /**
+ Specifies how to horizontally scroll. Acceptable values are
+ "scroll", "auto," "hidden," and "default". The precise
+ effect of the setting is determined by the scroll strategy.
+ */
+ horizontal: "default",
+ /**
+ Specifies how to vertically scroll. Acceptable values are "scroll",
+ "auto," "hidden," and "default". The precise effect of the setting
+ is determined by the scroll strategy.
+ */
+ vertical: "default",
+ /**
+ The vertical scroll position
+ */
+ scrollTop: 0,
+ /**
+ The horizontal scroll position
+ */
+ scrollLeft: 0,
+ /**
+ Maximum height of the scroll content
+ */
+ maxHeight: null,
+ /**
+ Set to true to make this scroller select a platform-appropriate
+ touch-based scrolling strategy. Note that if you specify a value for
+ _strategyKind_, that will take precedence over this setting.
+ */
+ touch: false,
+ /**
+ Specifies a type of scrolling. The scroller will attempt to
+ automatically select a strategy compatible with the runtime
+ environment. Alternatively, you may choose to use a specific
+ strategy:
+
+ * <a href="#enyo.ScrollStrategy">ScrollStrategy</a> is the default
+ and implements no scrolling, relying instead on the environment
+ to scroll properly.
+
+ * <a href="#enyo.TouchScrollStrategy">TouchScrollStrategy</a>
+ implements a touch scrolling mechanism.
+
+ * <a href="#enyo.TranslateScrollStrategy">TranslateScrollStrategy</a>
+ implements a touch scrolling mechanism using translations; it is
+ currently recommended only for Android 3 and 4 & Windows Phone 8.
+
+ * <a href="#enyo.TransitionScrollStrategy">TransitionScrollStrategy</a>
+ implements a touch scrolling mechanism using CSS transitions; it is
+ currently recommended only for iOS 5 and later.
+ */
+ strategyKind: "ScrollStrategy",
+ //* Set to true to display a scroll thumb in touch scrollers
+ thumb: true
+ },
+ events: {
+ //* Fires when a scrolling action starts.
+ onScrollStart: "",
+ //* Fires while a scrolling action is in progress.
+ onScroll: "",
+ //* Fires when a scrolling action stops.
+ onScrollStop: ""
+ },
+ /**
+ If true (the default) and a touch scroller, the scroller will overscroll
+ and bounce back at the edges
+ */
+ touchOverscroll: true,
+ /**
+ If true (the default), the scroller will not propagate _dragstart_
+ events that cause it to start scrolling
+ */
+ preventDragPropagation: true,
+ /**
+ If true, the scroller will not propagate scroll events
+ */
+ preventScrollPropagation: true,
+ //* @protected
+ handlers: {
+ onscroll: "domScroll",
+ onScrollStart: "scrollStart",
+ onScroll: "scroll",
+ onScrollStop: "scrollStop"
+ },
+ classes: "enyo-scroller",
+ statics: {
+ osInfo: [
+ {os: "android", version: 3},
+ {os: "androidChrome", version: 18},
+ {os: "androidFirefox", version: 16},
+ {os: "firefoxOS", version: 16},
+ {os: "ios", version: 5},
+ {os: "webos", version: 1e9},
+ {os: "blackberry", version:1e9}
+ ],
+ //* Returns true if platform should have touch events.
+ hasTouchScrolling: function() {
+ for (var i=0, t, m; (t=this.osInfo[i]); i++) {
+ if (enyo.platform[t.os]) {
+ return true;
+ }
+ }
+ // special detection for IE10+ on touch devices
+ if ((enyo.platform.ie >= 10 || enyo.platform.windowsPhone >= 8) && enyo.platform.touch) {
+ return true;
+ }
+ },
+ /**
+ Returns true if the platform has native div scrollers (desktop
+ browsers always have them).
+ */
+ hasNativeScrolling: function() {
+ for (var i=0, t, m; (t=this.osInfo[i]); i++) {
+ if (enyo.platform[t.os] < t.version) {
+ return false;
+ }
+ }
+ return true;
+ },
+ getTouchStrategy: function() {
+ return (enyo.platform.android >= 3) || (enyo.platform.windowsPhone === 8)
+ ? "TranslateScrollStrategy"
+ : "TouchScrollStrategy";
+ }
+ },
+ controlParentName: "strategy",
+ create: function() {
+ this.inherited(arguments);
+ this.horizontalChanged();
+ this.verticalChanged();
+ },
+ importProps: function(inProps) {
+ this.inherited(arguments);
+ // allow global overriding of strategy kind
+ if (inProps && inProps.strategyKind === undefined && (enyo.Scroller.touchScrolling || this.touch)) {
+ this.strategyKind = enyo.Scroller.getTouchStrategy();
+ }
+ },
+ initComponents: function() {
+ this.strategyKindChanged();
+ this.inherited(arguments);
+ },
+ teardownChildren: function() {
+ this.cacheScrollPosition();
+ this.inherited(arguments);
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ this.restoreScrollPosition();
+ },
+ strategyKindChanged: function() {
+ if (this.$.strategy) {
+ this.$.strategy.destroy();
+ this.controlParent = null;
+ }
+ // note: createComponents automatically updates controlParent.
+ this.createStrategy();
+ if (this.hasNode()) {
+ this.render();
+ }
+ },
+ createStrategy: function() {
+ this.createComponents([{name: "strategy", maxHeight: this.maxHeight,
+ kind: this.strategyKind, thumb: this.thumb,
+ preventDragPropagation: this.preventDragPropagation,
+ overscroll:this.touchOverscroll, isChrome: true}]);
+ },
+ getStrategy: function() {
+ return this.$.strategy;
+ },
+ maxHeightChanged: function() {
+ this.$.strategy.setMaxHeight(this.maxHeight);
+ },
+ showingChanged: function() {
+ if (!this.showing) {
+ this.cacheScrollPosition();
+ this.setScrollLeft(0);
+ this.setScrollTop(0);
+ }
+ this.inherited(arguments);
+ if (this.showing) {
+ this.restoreScrollPosition();
+ }
+ },
+ thumbChanged: function() {
+ this.$.strategy.setThumb(this.thumb);
+ },
+ cacheScrollPosition: function() {
+ this.cachedPosition = {left: this.getScrollLeft(), top: this.getScrollTop()};
+ },
+ restoreScrollPosition: function() {
+ if (this.cachedPosition) {
+ this.setScrollLeft(this.cachedPosition.left);
+ this.setScrollTop(this.cachedPosition.top);
+ this.cachedPosition = null;
+ }
+ },
+ horizontalChanged: function() {
+ this.$.strategy.setHorizontal(this.horizontal);
+ },
+ verticalChanged: function() {
+ this.$.strategy.setVertical(this.vertical);
+ },
+ // FIXME: these properties are virtual; property changed methods are fired only if
+ // property value changes, not if getter changes.
+ //* Sets scroll position along horizontal axis.
+ setScrollLeft: function(inLeft) {
+ this.scrollLeft = inLeft;
+ this.$.strategy.setScrollLeft(this.scrollLeft);
+ },
+ //* Sets scroll position along vertical axis.
+ setScrollTop: function(inTop) {
+ this.scrollTop = inTop;
+ this.$.strategy.setScrollTop(inTop);
+ },
+ //* Gets scroll position along horizontal axis.
+ getScrollLeft: function() {
+ return this.$.strategy.getScrollLeft();
+ },
+ //* Gets scroll position along vertical axis.
+ getScrollTop: function() {
+ return this.$.strategy.getScrollTop();
+ },
+ //* @public
+ /**
+ Returns an object describing the scroll boundaries with _height_ and
+ _width_ properties.
+ */
+ getScrollBounds: function() {
+ return this.$.strategy.getScrollBounds();
+ },
+ /**
+ Scrolls the given control (_inControl_) into view. If _inAlignWithTop_
+ is true, _inControl_ is aligned with the top of the scroller.
+ */
+ scrollIntoView: function(inControl, inAlignWithTop) {
+ this.$.strategy.scrollIntoView(inControl, inAlignWithTop);
+ },
+ //* Scrolls to the position specified by _inX_ and _inY_ in pixel units.
+ scrollTo: function(inX, inY) {
+ this.$.strategy.scrollTo(inX, inY);
+ },
+ /**
+ Ensures that the given control is visible in the scroller's viewport.
+ Unlike _scrollIntoView_, which uses DOM's _scrollIntoView_, this only
+ affects the current scroller.
+ */
+ scrollToControl: function(inControl, inAlignWithTop) {
+ this.scrollToNode(inControl.hasNode(), inAlignWithTop);
+ },
+ //* Ensures that the given node is visible in the scroller's viewport.
+ scrollToNode: function(inNode, inAlignWithTop) {
+ this.$.strategy.scrollToNode(inNode, inAlignWithTop);
+ },
+ //* @protected
+ //* Normalizes scroll event to _onScroll_.
+ domScroll: function(inSender, e) {
+ // if a scroll event originated here, pass it to our strategy to handle
+ if (this.$.strategy.domScroll && e.originator == this) {
+ this.$.strategy.scroll(inSender, e);
+ }
+ this.doScroll(e);
+ return true;
+ },
+ /**
+ Returns true if the current scroll event should be stopped; false if it
+ should be allowed to propagate.
+ */
+ shouldStopScrollEvent: function(inEvent) {
+ return (this.preventScrollPropagation &&
+ inEvent.originator.owner != this.$.strategy);
+ },
+ /**
+ Calls _shouldStopScrollEvent_ to determine whether current scroll event
+ should be stopped.
+ */
+ scrollStart: function(inSender, inEvent) {
+ return this.shouldStopScrollEvent(inEvent);
+ },
+ //* Either propagates or stops the current scroll event.
+ scroll: function(inSender, inEvent) {
+ // note: scroll event can be native dom or generated.
+ if (inEvent.dispatchTarget) {
+ // allow a dom event if it orignated with this scroller or its strategy
+ return this.preventScrollPropagation && !(inEvent.originator == this ||
+ inEvent.originator.owner == this.$.strategy);
+ } else {
+ return this.shouldStopScrollEvent(inEvent);
+ }
+ },
+ /**
+ Calls _shouldStopScrollEvent_ to determine whether current scroll event
+ should be stopped.
+ */
+ scrollStop: function(inSender, inEvent) {
+ return this.shouldStopScrollEvent(inEvent);
+ },
+ //* @public
+ //* Scroll to the top of the scrolling region.
+ scrollToTop: function() {
+ this.setScrollTop(0);
+ },
+ //* Scroll to the bottom of the scrolling region.
+ scrollToBottom: function() {
+ this.setScrollTop(this.getScrollBounds().maxTop);
+ },
+ //* Scroll to the right edge of the scrolling region.
+ scrollToRight: function() {
+ this.setScrollLeft(this.getScrollBounds().maxLeft);
+ },
+ //* Scroll to the left edge of the scrolling region.
+ scrollToLeft: function() {
+ this.setScrollLeft(0);
+ },
+ //* Ensures scroll position is in bounds.
+ stabilize: function() {
+ var s = this.getStrategy();
+ if (s.stabilize) {
+ s.stabilize();
+ }
+ }
+});
+
+// provide a touch scrolling solution by default when the environment is mobile
+if (enyo.Scroller.hasTouchScrolling()) {
+ enyo.Scroller.prototype.strategyKind = enyo.Scroller.getTouchStrategy();
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchThumbcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/Thumb.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/Thumb.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/Thumb.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+.enyo-thumb {
+ position: absolute;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ border-radius: 4px;
+ background: #333;
+ border: 1px solid #666;
+ opacity: 0.75;
+ z-index: 1;
+}
+
+.enyo-vthumb {
+ top: 0;
+ right: 2px;
+ width: 4px;
+}
+
+.enyo-hthumb {
+ left: 0;
+ bottom: 2px;
+ height: 4px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchThumbjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/Thumb.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/Thumb.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/Thumb.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,111 @@
</span><ins>+/**
+_enyo.ScrollThumb_ is a helper kind used by
+<a href="#enyo.TouchScrollStrategy">enyo.TouchScrollStrategy</a> and
+<a href="#enyo.TranslateScrollStrategy">enyo.TranslateScrollStrategy</a> to
+display a small visual scroll indicator.
+
+_enyo.ScrollThumb_ is not typically created in application code.
+*/
+
+enyo.kind({
+ name: "enyo.ScrollThumb",
+ //* The orientation of the scroll indicator bar; "v" for vertical or "h" for horizontal
+ axis: "v",
+ //* @protected
+ //* Minimum size of the indicator
+ minSize: 4,
+ //* Size of the corners of the indicator
+ cornerSize: 6,
+ classes: "enyo-thumb",
+ create: function() {
+ this.inherited(arguments);
+ var v = this.axis == "v";
+ this.dimension = v ? "height" : "width";
+ this.offset = v ? "top" : "left";
+ this.translation = v ? "translateY" : "translateX";
+ this.positionMethod = v ? "getScrollTop" : "getScrollLeft";
+ this.sizeDimension = v ? "clientHeight" : "clientWidth";
+ this.addClass("enyo-" + this.axis + "thumb");
+ this.transform = enyo.dom.canTransform();
+ if (enyo.dom.canAccelerate()) {
+ enyo.dom.transformValue(this, "translateZ", 0);
+ }
+ },
+ //* Syncs the scroll indicator bar to the scroller size and position,
+ //* as determined by the passed-in scroll strategy.
+ sync: function(inStrategy) {
+ this.scrollBounds = inStrategy._getScrollBounds();
+ this.update(inStrategy);
+ },
+ update: function(inStrategy) {
+ if (this.showing) {
+ var d = this.dimension, o = this.offset;
+ var bd = this.scrollBounds[this.sizeDimension], sbd = this.scrollBounds[d];
+ var overs = 0, overp = 0, over = 0;
+ if (bd >= sbd) {
+ this.hide();
+ return;
+ }
+ if (inStrategy.isOverscrolling()) {
+ over = inStrategy.getOverScrollBounds()["over" + o];
+ overs = Math.abs(over);
+ overp = Math.max(over, 0);
+ }
+ var sbo = inStrategy[this.positionMethod]() - over;
+ // calc size & position
+ var bdc = bd - this.cornerSize;
+ var s = Math.floor((bd * bd / sbd) - overs);
+ s = Math.max(this.minSize, s);
+ var p = Math.floor((bdc * sbo / sbd) + overp);
+ p = Math.max(0, Math.min(bdc - this.minSize, p));
+ // apply thumb styling
+ this.needed = s < bd;
+ if (this.needed && this.hasNode()) {
+ if (this._pos !== p) {
+ this._pos = p;
+ if(!this.transform) {
+ //adjust top/left for browsers that don't support translations
+ if(this.axis=="v") {
+ this.setBounds({top:p + "px"});
+ } else {
+ this.setBounds({left:p + "px"});
+ }
+ } else {
+ enyo.dom.transformValue(this, this.translation, p + "px");
+ }
+ }
+ if (this._size !== s) {
+ this._size = s;
+ this.node.style[d] = this.domStyles[d] = s + "px";
+ }
+ } else {
+ this.hide();
+ }
+ }
+ },
+ // implement set because showing is not changed while
+ // we delayHide but we want to cancel the hide.
+ setShowing: function(inShowing) {
+ if (inShowing && inShowing != this.showing) {
+ if (this.scrollBounds[this.sizeDimension] >= this.scrollBounds[this.dimension]) {
+ return;
+ }
+ }
+ if (this.hasNode()) {
+ this.cancelDelayHide();
+ }
+ if (inShowing != this.showing) {
+ var last = this.showing;
+ this.showing = inShowing;
+ this.showingChanged(last);
+ }
+ },
+ delayHide: function(inDelay) {
+ if (this.showing) {
+ enyo.job(this.id + "hide", enyo.bind(this, "hide"), inDelay || 0);
+ }
+ },
+ cancelDelayHide: function() {
+ enyo.job.stop(this.id + "hide");
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchTouchScrollStrategyjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/TouchScrollStrategy.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/TouchScrollStrategy.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/TouchScrollStrategy.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,429 @@
</span><ins>+/**
+ _enyo.TouchScrollStrategy_ is a helper kind for implementing a touch-based
+ scroller. It integrates the scrolling simulation provided by
+ <a href="#enyo.ScrollMath">enyo.ScrollMath</a> into an
+ <a href="#enyo.Scroller">enyo.Scroller</a>.
+
+ _enyo.TouchScrollStrategy_ is not typically created in application code.
+ Instead, it is specified as the value of the `strategyKind` property of an
+ `enyo.Scroller` or <a href="#enyo.List">enyo.List</a>, or is used by the
+ framework implicitly.
+*/
+enyo.kind({
+ name: "enyo.TouchScrollStrategy",
+ kind: "ScrollStrategy",
+ /**
+ If true (the default), the scroller will overscroll and bounce back at the edges
+ */
+ overscroll: true,
+ /**
+ If true (the default), the scroller will not propagate _dragstart_
+ events that cause it to start scrolling
+ */
+ preventDragPropagation: true,
+ published: {
+ /**
+ Specifies how to vertically scroll. Acceptable values are:
+
+ * "scroll": Always scroll.
+ * "auto": Scroll only if the content overflows the scroller.
+ * "hidden": Never scroll.
+ * "default": In touch environments, the default vertical scrolling
+ behavior is to always scroll. If the content does not overflow
+ the scroller, the scroller will overscroll and snap back.
+ */
+ vertical: "default",
+ /**
+ Specifies how to horizontally scroll. Acceptable values are:
+
+ * "scroll": Always scroll.
+ * "auto": Scroll only if the content overflows the scroller.
+ * "hidden": Never scroll.
+ * "default": Same as "auto".
+ */
+ horizontal: "default",
+ //* Set to true to display a scroll thumb
+ thumb: true,
+ /**
+ Set to true to display a transparent overlay while scrolling. This
+ can help improve performance of complex, large scroll regions on
+ some platforms (e.g., Android).
+ */
+ scrim: false,
+ //* Allow drag events sent when gesture events are happening simultaneously
+ dragDuringGesture: true
+ },
+ events: {
+ onShouldDrag: ""
+ },
+ //* @protected
+ handlers: {
+ onscroll: "domScroll",
+ onflick: "flick",
+ onhold: "hold",
+ ondragstart: "dragstart",
+ onShouldDrag: "shouldDrag",
+ ondrag: "drag",
+ ondragfinish: "dragfinish",
+ onmousewheel: "mousewheel"
+ },
+ tools: [
+ {kind: "ScrollMath", onScrollStart: "scrollMathStart", onScroll: "scrollMathScroll", onScrollStop: "scrollMathStop"},
+ {name: "vthumb", kind: "ScrollThumb", axis: "v", showing: false},
+ {name: "hthumb", kind: "ScrollThumb", axis: "h", showing: false}
+ ],
+ scrimTools: [{name: "scrim", classes: "enyo-fit", style: "z-index: 1;", showing: false}],
+ components: [
+ {name: "client", classes: "enyo-touch-scroller"}
+ ],
+ // flag telling us whether the list is currently reordering
+ listReordering: false,
+ create: function() {
+ this.inherited(arguments);
+ this.transform = enyo.dom.canTransform();
+ if(!this.transform) {
+ if(this.overscroll) {
+ //so we can adjust top/left if browser can't handle translations
+ this.$.client.applyStyle("position", "relative");
+ }
+ }
+ this.accel = enyo.dom.canAccelerate();
+ var containerClasses = "enyo-touch-strategy-container";
+ // note: needed for ios to avoid incorrect clipping of thumb
+ // and need to avoid on Android as it causes problems hiding the thumb
+ if (enyo.platform.ios && this.accel) {
+ containerClasses += " enyo-composite";
+ }
+ this.scrimChanged();
+ this.container.addClass(containerClasses);
+ this.translation = this.accel ? "translate3d" : "translate";
+ },
+ initComponents: function() {
+ this.createChrome(this.tools);
+ this.inherited(arguments);
+ },
+ destroy: function() {
+ this.container.removeClass("enyo-touch-strategy-container");
+ this.inherited(arguments);
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ enyo.makeBubble(this.$.client, "scroll");
+ this.calcBoundaries();
+ this.syncScrollMath();
+ if (this.thumb) {
+ this.alertThumbs();
+ }
+ },
+ scrimChanged: function() {
+ if (this.scrim && !this.$.scrim) {
+ this.makeScrim();
+ }
+ if (!this.scrim && this.$.scrim) {
+ this.$.scrim.destroy();
+ }
+ },
+ makeScrim: function() {
+ // reset control parent so scrim doesn't go into client.
+ var cp = this.controlParent;
+ this.controlParent = null;
+ this.createChrome(this.scrimTools);
+ this.controlParent = cp;
+ var cn = this.container.hasNode();
+ // render scrim in container, strategy has no dom.
+ if (cn) {
+ this.$.scrim.parentNode = cn;
+ this.$.scrim.render();
+ }
+ },
+ //* Whether or not the scroller is actively moving
+ isScrolling: function() {
+ var m = this.$.scrollMath;
+ return m ? m.isScrolling() : this.scrolling;
+ },
+ //* Whether or not the scroller is in overscrolling
+ isOverscrolling: function() {
+ var m = this.$.scrollMath || this;
+ return (this.overscroll) ? m.isInOverScroll() : false;
+ },
+ domScroll: function() {
+ if (!this.isScrolling()) {
+ this.calcBoundaries();
+ this.syncScrollMath();
+ if (this.thumb) {
+ this.alertThumbs();
+ }
+ }
+ },
+ horizontalChanged: function() {
+ this.$.scrollMath.horizontal = (this.horizontal != "hidden");
+ },
+ verticalChanged: function() {
+ this.$.scrollMath.vertical = (this.vertical != "hidden");
+ },
+ maxHeightChanged: function() {
+ this.$.client.applyStyle("max-height", this.maxHeight);
+ // note: previously used enyo-fit here but IE would reset scroll position when the scroll thumb
+ // was hidden; in general IE resets scrollTop when there are 2 abs position siblings, one has
+ // scrollTop and the other is hidden.
+ this.$.client.addRemoveClass("enyo-scrollee-fit", !this.maxHeight);
+ },
+ thumbChanged: function() {
+ this.hideThumbs();
+ },
+ stop: function() {
+ if (this.isScrolling()) {
+ this.$.scrollMath.stop(true);
+ }
+ },
+ stabilize: function() {
+ if(this.$.scrollMath) {
+ this.$.scrollMath.stabilize();
+ }
+ },
+ //* Scrolls to specific x/y positions within the scroll area.
+ scrollTo: function(inX, inY) {
+ this.stop();
+ this.$.scrollMath.scrollTo(inX, inY || inY === 0 ? inY : null);
+ },
+ scrollIntoView: function() {
+ this.stop();
+ this.inherited(arguments);
+ },
+ //* Sets the left scroll position within the scroller.
+ setScrollLeft: function() {
+ this.stop();
+ this.inherited(arguments);
+ },
+ //* Sets the top scroll position within the scroller.
+ setScrollTop: function() {
+ this.stop();
+ this.inherited(arguments);
+ },
+ //* Gets the left scroll position within the scroller.
+ getScrollLeft: function() {
+ return this.isScrolling() ? this.scrollLeft : this.inherited(arguments);
+ },
+ //* Gets the top scroll position within the scroller.
+ getScrollTop: function() {
+ return this.isScrolling() ? this.scrollTop : this.inherited(arguments);
+ },
+ calcScrollNode: function() {
+ return this.$.client.hasNode();
+ },
+ calcAutoScrolling: function() {
+ var v = (this.vertical == "auto");
+ var h = (this.horizontal == "auto") || (this.horizontal == "default");
+ if ((v || h) && this.scrollNode) {
+ var b = this.getScrollBounds();
+ if (v) {
+ this.$.scrollMath.vertical = b.height > b.clientHeight;
+ }
+ if (h) {
+ this.$.scrollMath.horizontal = b.width > b.clientWidth;
+ }
+ }
+ },
+ shouldDrag: function(inSender, e) {
+ this.calcAutoScrolling();
+ var requestV = e.vertical;
+ var canH = this.$.scrollMath.horizontal && !requestV;
+ var canV = this.$.scrollMath.vertical && requestV;
+ var down = e.dy < 0, right = e.dx < 0;
+ var oobV = (!down && this.startEdges.top || down && this.startEdges.bottom);
+ var oobH = (!right && this.startEdges.left || right && this.startEdges.right);
+ // we would scroll if not at a boundary
+ if (!e.boundaryDragger && (canH || canV)) {
+ e.boundaryDragger = this;
+ }
+ // include boundary exclusion
+ if ((!oobV && canV) || (!oobH && canH)) {
+ e.dragger = this;
+ return true;
+ }
+ },
+ flick: function(inSender, e) {
+ var onAxis = Math.abs(e.xVelocity) > Math.abs(e.yVelocity) ? this.$.scrollMath.horizontal : this.$.scrollMath.vertical;
+ if (onAxis && this.dragging) {
+ this.$.scrollMath.flick(e);
+ return this.preventDragPropagation;
+ }
+ },
+ hold: function(inSender, e) {
+ if (this.isScrolling() && !this.isOverscrolling()) {
+ var m = this.$.scrollMath || this;
+ m.stop(e);
+ return true;
+ }
+ },
+ move: function(inSender, inEvent) {
+ },
+ // Special synthetic DOM events served up by the Gesture system
+ dragstart: function(inSender, inEvent) {
+ // Ignore drags sent from multi-touch events
+ if(!this.dragDuringGesture && inEvent.srcEvent.touches && inEvent.srcEvent.touches.length > 1) {
+ return true;
+ }
+ // note: allow drags to propagate to parent scrollers via data returned in the shouldDrag event.
+ this.doShouldDrag(inEvent);
+ this.dragging = (inEvent.dragger == this || (!inEvent.dragger && inEvent.boundaryDragger == this));
+ if (this.dragging) {
+ inEvent.preventDefault();
+ // note: needed because show/hide changes
+ // the position so sync'ing is required when
+ // dragging begins (needed because show/hide does not trigger onscroll)
+ this.syncScrollMath();
+ this.$.scrollMath.startDrag(inEvent);
+ if (this.preventDragPropagation) {
+ return true;
+ }
+ }
+ },
+ drag: function(inSender, inEvent) {
+ // if the list is doing a reorder, don't scroll
+ if(this.listReordering) {
+ return false;
+ }
+ if (this.dragging) {
+ inEvent.preventDefault();
+ this.$.scrollMath.drag(inEvent);
+ if (this.scrim) {
+ this.$.scrim.show();
+ }
+ }
+ },
+ dragfinish: function(inSender, inEvent) {
+ if (this.dragging) {
+ inEvent.preventTap();
+ this.$.scrollMath.dragFinish();
+ this.dragging = false;
+ if (this.scrim) {
+ this.$.scrim.hide();
+ }
+ }
+ },
+ mousewheel: function(inSender, e) {
+ if (!this.dragging) {
+ this.calcBoundaries();
+ this.syncScrollMath();
+ this.stabilize();
+ if (this.$.scrollMath.mousewheel(e)) {
+ e.preventDefault();
+ return true;
+ }
+ }
+ },
+ scrollMathStart: function(inSender) {
+ if (this.scrollNode) {
+ this.calcBoundaries();
+ if (this.thumb) {
+ this.showThumbs();
+ }
+ }
+ },
+ scrollMathScroll: function(inSender) {
+ if(!this.overscroll) {
+ //don't overscroll past edges
+ this.effectScroll(-Math.min(inSender.leftBoundary, Math.max(inSender.rightBoundary, inSender.x)),
+ -Math.min(inSender.topBoundary, Math.max(inSender.bottomBoundary, inSender.y)));
+ } else {
+ this.effectScroll(-inSender.x, -inSender.y);
+ }
+ if (this.thumb) {
+ this.updateThumbs();
+ }
+ },
+ scrollMathStop: function(inSender) {
+ this.effectScrollStop();
+ if (this.thumb) {
+ this.delayHideThumbs(100);
+ }
+ },
+ calcBoundaries: function() {
+ var s = this.$.scrollMath || this, b = this._getScrollBounds();
+ s.bottomBoundary = b.clientHeight - b.height;
+ s.rightBoundary = b.clientWidth - b.width;
+ },
+ syncScrollMath: function() {
+ var m = this.$.scrollMath;
+ if(m) {
+ m.setScrollX(-this.getScrollLeft());
+ m.setScrollY(-this.getScrollTop());
+ }
+ },
+ effectScroll: function(inX, inY) {
+ if (this.scrollNode) {
+ this.scrollLeft = this.scrollNode.scrollLeft = inX;
+ this.scrollTop = this.scrollNode.scrollTop = inY;
+ this.effectOverscroll(Math.round(inX), Math.round(inY));
+ }
+ },
+ effectScrollStop: function() {
+ this.effectOverscroll(null, null);
+ },
+ effectOverscroll: function(inX, inY) {
+ var n = this.scrollNode;
+ var x = "0", y = "0", z = this.accel ? ",0" : "";
+ if (inY !== null && Math.abs(inY - n.scrollTop) > 1) {
+ y = (n.scrollTop - inY);
+ }
+ if (inX !== null && Math.abs(inX - n.scrollLeft) > 1) {
+ x = (n.scrollLeft - inX);
+ }
+ if(!this.transform) {
+ //adjust top/left if browser can't handle translations
+ this.$.client.setBounds({left:x + "px", top:y + "px"});
+ } else {
+ enyo.dom.transformValue(this.$.client, this.translation, x + "px, " + y + "px" + z);
+ }
+ },
+ //* Returns the values of _overleft_ and _overtop_, if any.
+ getOverScrollBounds: function() {
+ var m = this.$.scrollMath || this;
+ return {
+ overleft: Math.min(m.leftBoundary - m.x, 0) || Math.max(m.rightBoundary - m.x, 0),
+ overtop: Math.min(m.topBoundary - m.y, 0) || Math.max(m.bottomBoundary - m.y, 0)
+ };
+ },
+ _getScrollBounds: function() {
+ var r = this.inherited(arguments);
+ enyo.mixin(r, this.getOverScrollBounds());
+ return r;
+ },
+ getScrollBounds: function() {
+ this.stop();
+ return this.inherited(arguments);
+ },
+ // Thumb processing
+ alertThumbs: function() {
+ this.showThumbs();
+ this.delayHideThumbs(500);
+ },
+ //* Syncs the vertical and horizontal scroll indicators.
+ syncThumbs: function() {
+ this.$.vthumb.sync(this);
+ this.$.hthumb.sync(this);
+ },
+ updateThumbs: function() {
+ this.$.vthumb.update(this);
+ this.$.hthumb.update(this);
+ },
+ //* Syncs and shows both the vertical and horizontal scroll indicators.
+ showThumbs: function() {
+ this.syncThumbs();
+ if (this.horizontal != "hidden")
+ this.$.hthumb.show();
+ if (this.vertical != "hidden")
+ this.$.vthumb.show();
+ },
+ //* Hides the vertical and horizontal scroll indicators.
+ hideThumbs: function() {
+ this.$.vthumb.hide();
+ this.$.hthumb.hide();
+ },
+ //* Hides the vertical and horizontal scroll indicators asynchronously.
+ delayHideThumbs: function(inDelay) {
+ this.$.vthumb.delayHide(inDelay);
+ this.$.hthumb.delayHide(inDelay);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchTransitionScrollStrategyjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/TransitionScrollStrategy.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/TransitionScrollStrategy.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/TransitionScrollStrategy.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,616 @@
</span><ins>+/**
+ _enyo.TransitionScrollStrategy_ is a helper kind that extends
+ <a href="#enyo.TouchScrollStrategy">enyo.TouchScrollStrategy</a>, optimizing
+ it for scrolling environments in which effecting scroll changes with
+ transforms using CSS transitions is fastest.
+
+ _enyo.TransitionScrollStrategy_ is not typically created in application code.
+ Instead, it is specified as the value of the `strategyKind` property of an
+ `enyo.Scroller` or <a href="#enyo.List">enyo.List</a>, or is used by the
+ framework implicitly.
+*/
+enyo.kind({
+ name: "enyo.TransitionScrollStrategy",
+ kind: "enyo.TouchScrollStrategy",
+ //* @protected
+ components: [
+ {name: "clientContainer", classes: "enyo-touch-scroller", components: [
+ {name: "client"}
+ ]}
+ ],
+ events: {
+ onScrollStart: "",
+ onScroll: "",
+ onScrollStop: ""
+ },
+ handlers: {
+ ondown: "down",
+ ondragfinish: "dragfinish",
+ onwebkitTransitionEnd: "transitionComplete"
+ },
+ //* No scrollMath tool for this strategy
+ tools: [
+ {name: "vthumb", kind: "ScrollThumb", axis: "v", showing: true},
+ {name: "hthumb", kind: "ScrollThumb", axis: "h", showing: false}
+ ],
+ //* Scalar applied to 'flick' event velocity
+ kFlickScalar: 600,
+ //* Top snap boundary, generally 0
+ topBoundary: 0,
+ //* Right snap boundary, generally (viewport width - content width)
+ rightBoundary: 0,
+ //* Bottom snap boundary, generally (viewport height - content height)
+ bottomBoundary: 0,
+ //* Left snap boundary, generally 0
+ leftBoundary: 0,
+ //* Flag to specify whether scrolling is in progress
+ scrolling: false,
+ //* Event listener for webkit transition completion
+ listener: null,
+ //* X Distance to scroll into overscroll space before bouncing back
+ boundaryX:0,
+ //* Y Distance to scroll into overscroll space before bouncing back
+ boundaryY:0,
+ //* Timeout used to stop scrolling on mousedown
+ stopTimeout: null,
+ //* MS delay used to stop scrolling on mousedown
+ stopTimeoutMS: 80,
+ //* Interval used to update scroll values and bubble scroll events during scroll animation
+ scrollInterval: null,
+ //* MS delay used to update scroll values and bubble scroll events during scroll animation
+ scrollIntervalMS: 50,
+ //* Transition animations
+ transitions: {
+ //* None - used for dragging, etc.
+ none : "",
+ //* Scroll - basic scrolling behavior
+ scroll : "3.8s cubic-bezier(.19,1,.28,1.0) 0s",
+ //* Bounce - overscroll bounceback behavior
+ bounce : "0.5s cubic-bezier(0.06,.5,.5,.94) 0s"
+ },
+
+ //* @public
+
+ //* Sets the left scroll position within the scroller.
+ setScrollLeft: function(inLeft) {
+ var prevLeft = this.scrollLeft;
+ this.stop();
+ this.scrollLeft = inLeft;
+ if(this.isInLeftOverScroll() || this.isInRightOverScroll()) {
+ this.scrollLeft = prevLeft;
+ }
+ this.effectScroll();
+ },
+ //* Sets the top scroll position within the scroller.
+ setScrollTop: function(inTop) {
+ var prevTop = this.scrollTop;
+ this.stop();
+ this.scrollTop = inTop;
+ if(this.isInTopOverScroll() || this.isInBottomOverScroll()) {
+ this.scrollTop = prevTop;
+ }
+ this.effectScroll();
+ },
+ setScrollX: function(inLeft) {
+ this.scrollLeft = -1*inLeft;
+ },
+ setScrollY: function(inTop) {
+ this.scrollTop = -1*inTop;
+ },
+
+ //* Gets the left scroll position within the scroller.
+ getScrollLeft: function() {
+ return this.scrollLeft;
+ },
+ //* Gets the top scroll position within the scroller.
+ getScrollTop: function() {
+ return this.scrollTop;
+ },
+
+ //* @protected
+
+ // apply initial transform so we're always composited
+ create: function() {
+ this.inherited(arguments);
+ enyo.dom.transformValue(this.$.client, this.translation, "0,0,0");
+ },
+ destroy: function() {
+ this.clearCSSTransitionInterval();
+ this.inherited(arguments);
+ },
+ getScrollSize: function() {
+ var n = this.$.client.hasNode();
+ return {width: n ? n.scrollWidth : 0, height: n ? n.scrollHeight : 0};
+ },
+ horizontalChanged: function() {
+ if(this.horizontal == "hidden") {
+ this.scrollHorizontal = false;
+ }
+ },
+ verticalChanged: function() {
+ if(this.vertical == "hidden") {
+ this.scrollVertical = false;
+ }
+ },
+ calcScrollNode: function() {
+ return this.$.clientContainer.hasNode();
+ },
+ calcBoundaries: function() {
+ var b = this._getScrollBounds();
+ this.bottomBoundary = b.clientHeight - b.height;
+ this.rightBoundary = b.clientWidth - b.width;
+ },
+ maxHeightChanged: function() {
+ // content should cover scroller at a minimum if there's no max-height.
+ this.$.client.applyStyle("min-height", this.maxHeight ? null : "100%");
+ this.$.client.applyStyle("max-height", this.maxHeight);
+ this.$.clientContainer.addRemoveClass("enyo-scrollee-fit", !this.maxHeight);
+ },
+ calcAutoScrolling: function() {
+ var b = this.getScrollBounds();
+ if(this.vertical) {
+ this.scrollVertical = b.height > b.clientHeight;
+ }
+ if(this.horizontal) {
+ this.scrollHorizontal = b.width > b.clientWidth;
+ }
+ },
+ isInOverScroll: function() {
+ return (this.isInTopOverScroll() || this.isInBottomOverScroll() || this.isInLeftOverScroll() || this.isInRightOverScroll());
+ },
+ isInLeftOverScroll: function() {
+ return (this.getScrollLeft() < this.leftBoundary);
+ },
+ isInRightOverScroll: function() {
+ if(this.getScrollLeft <= 0) {
+ return false;
+ } else {
+ return (this.getScrollLeft()*-1 < this.rightBoundary);
+ }
+ },
+ isInTopOverScroll: function() {
+ return (this.getScrollTop() < this.topBoundary);
+ },
+ isInBottomOverScroll: function() {
+ if(this.getScrollTop() <= 0) {
+ return false;
+ } else {
+ return (this.getScrollTop()*-1 < this.bottomBoundary);
+ }
+ },
+ calcStartInfo: function() {
+ var sb = this.getScrollBounds(), y = this.getScrollTop(), x = this.getScrollLeft();
+ this.startEdges = {
+ top: y === 0,
+ bottom: y === sb.maxTop,
+ left: x === 0,
+ right: x === sb.maxLeft
+ };
+ },
+ mousewheel: function(inSender, e) {
+ if (!this.dragging) {
+ this.calcBoundaries();
+ this.syncScrollMath();
+ this.stabilize();
+ var dy = this.vertical ? e.wheelDeltaY || e.wheelDelta : 0;
+ var y = parseFloat(this.getScrollTop()) + -1*parseFloat(dy);
+ y = (y*-1 < this.bottomBoundary) ? -1*this.bottomBoundary : (y < this.topBoundary) ? this.topBoundary : y;
+ this.setScrollTop(y);
+ this.doScroll();
+ e.preventDefault();
+ return true;
+ }
+ },
+ // Update thumbs, recalculate boundaries, and bubble scroll event
+ scroll: function(inSender, inEvent) {
+ if(this.thumb) {
+ this.updateThumbs();
+ }
+ this.calcBoundaries();
+ this.doScroll();
+ },
+ // Scroll to current x,y coordinates and bubble scrollstart event
+ start: function() {
+ this.startScrolling();
+ this.doScrollStart();
+ },
+ // If scrolling, stop. Hide thumbs and bubble scrollstop event.
+ stop: function() {
+ if(this.isScrolling()) {
+ this.stopScrolling();
+ }
+ if (this.thumb) {
+ this.delayHideThumbs(100);
+ }
+ this.doScrollStop();
+ },
+
+ // Set scroll x value to the current computed style
+ updateX: function() {
+ var x = window.getComputedStyle(this.$.client.node,null).getPropertyValue(enyo.dom.getCssTransformProp()).split('(')[1];
+ x = (x == undefined) ? 0 : x.split(')')[0].split(',')[4];
+ if(-1*parseFloat(x) === this.scrollLeft) {
+ return false;
+ }
+ this.scrollLeft = -1*parseFloat(x);
+ return true;
+ },
+ // Set scroll y value to the current computed style
+ updateY: function() {
+ var y = window.getComputedStyle(this.$.client.node,null).getPropertyValue(enyo.dom.getCssTransformProp()).split('(')[1];
+ y = (y == undefined) ? 0 : y.split(')')[0].split(',')[5];
+ if(-1*parseFloat(y) === this.scrollTop) {
+ return false;
+ }
+ this.scrollTop = -1*parseFloat(y);
+ return true;
+ },
+ // Apply transform to scroll the scroller
+ effectScroll: function() {
+ var o = (-1*this.scrollLeft) + "px, " + (-1*this.scrollTop) + "px" + (this.accel ? ", 0" : "");
+ enyo.dom.transformValue(this.$.client, this.translation, o);
+ },
+ // On touch, stop transition by setting transform values to current computed style, and
+ // changing transition time to 0s. TODO
+ down: function(inSender, inEvent) {
+ var _this = this;
+ if (this.isScrolling() && !this.isOverscrolling()) {
+ this.stopTimeout = setTimeout(function() { _this.stop(); }, this.stopTimeoutMS);
+ return true;
+ }
+ },
+ // Special synthetic DOM events served up by the Gesture system
+ dragstart: function(inSender, inEvent) {
+ if(this.stopTimeout) {
+ clearTimeout(this.stopTimeout);
+ }
+ // Ignore drags sent from multi-touch events
+ if(!this.dragDuringGesture && inEvent.srcEvent.touches && inEvent.srcEvent.touches.length > 1) {
+ return true;
+ }
+ this.shouldDrag(inEvent);
+ this.dragging = (inEvent.dragger == this || (!inEvent.dragger && inEvent.boundaryDragger == this));
+ if (this.dragging) {
+ if(this.isScrolling()) {
+ this.stopScrolling();
+ }
+ if(this.thumb) {
+ this.showThumbs();
+ }
+ inEvent.preventDefault();
+ this.prevY = inEvent.pageY;
+ this.prevX = inEvent.pageX;
+ if (this.preventDragPropagation) {
+ return true;
+ }
+ }
+ },
+ // Determine if we should allow dragging
+ shouldDrag: function(e) {
+ this.calcStartInfo();
+ this.calcBoundaries();
+ this.calcAutoScrolling();
+ if(!this.scrollHorizontal) {
+ return this.shouldDragVertical(e);
+ } else {
+ if(!this.scrollVertical) {
+ return this.shouldDragHorizontal(e);
+ } else {
+ return (this.shouldDragVertical(e) || this.shouldDragHorizontal(e));
+ }
+ }
+ },
+ shouldDragVertical: function(e) {
+ var canV = this.canDragVertical(e);
+ var oobV = this.oobVertical(e);
+ // scroll if not at a boundary
+ if (!e.boundaryDragger && canV) {
+ e.boundaryDragger = this;
+ }
+ // include boundary exclusion
+ if (!oobV && canV) {
+ e.dragger = this;
+ return true;
+ }
+ },
+ shouldDragHorizontal: function(e) {
+ var canH = this.canDragHorizontal(e);
+ var oobH = this.oobHorizontal(e);
+ // scroll if not at a boundary
+ if (!e.boundaryDragger && canH) {
+ e.boundaryDragger = this;
+ }
+ // include boundary exclusion
+ if (!oobH && canH) {
+ e.dragger = this;
+ return true;
+ }
+ },
+ canDragVertical: function(e) {
+ return (this.scrollVertical && e.vertical);
+ },
+ canDragHorizontal: function(e) {
+ return (this.scrollHorizontal && !e.vertical);
+ },
+ oobVertical: function(e) {
+ var down = e.dy < 0;
+ return (!down && this.startEdges.top || down && this.startEdges.bottom);
+ },
+ oobHorizontal: function(e) {
+ var right = e.dx < 0;
+ return (!right && this.startEdges.left || right && this.startEdges.right);
+ },
+ // Move scroller based on user's dragging
+ drag: function(inSender, e) {
+ // if the list is doing a reorder, don't scroll
+ if(this.listReordering) {
+ return false;
+ }
+ // if shouldDrag() set this.dragging to true
+ if(this.dragging) {
+ e.preventDefault();
+ // calculate new scroll values
+ this.scrollLeft = this.scrollHorizontal ?
+ this.calculateDragDistance(parseInt(this.getScrollLeft(), 10), (-1*(e.pageX-this.prevX)), this.leftBoundary, this.rightBoundary) :
+ this.getScrollLeft();
+ this.scrollTop = this.scrollVertical ?
+ this.calculateDragDistance(this.getScrollTop(), (-1*(e.pageY-this.prevY)), this.topBoundary, this.bottomBoundary) :
+ this.getScrollTop();
+ // apply new scroll values
+ this.effectScroll();
+ this.scroll();
+ // save values for next drag
+ this.prevY = e.pageY;
+ this.prevX = e.pageX;
+ this.resetBoundaryX();
+ this.resetBoundaryY();
+ }
+ },
+ //* Figure how far the drag should go based on pointer movement (delta)
+ calculateDragDistance: function(currentPosition, delta, aBoundary, bBoundary) {
+ var newPosition = currentPosition + delta;
+ return this.overscrollDragDamping(currentPosition, newPosition,delta,aBoundary,bBoundary);
+ },
+ //* Provides resistance against dragging into overscroll
+ overscrollDragDamping: function(currentPosition, newPosition, delta, aBoundary, bBoundary) {
+ if(newPosition < aBoundary || newPosition*-1 < bBoundary) {
+ delta /= 2;
+ newPosition = currentPosition + delta;
+ }
+ return newPosition;
+ },
+ resetBoundaryX: function() {
+ this.boundaryX = 0;
+ },
+ resetBoundaryY: function() {
+ this.boundaryY = 0;
+ },
+ // When user releases the drag, set this.dragging to false, bounce overflow back, and hide scrim.
+ dragfinish: function(inSender, inEvent) {
+ if (this.dragging) {
+ inEvent.preventTap();
+ this.dragging = false;
+ if(!this.isScrolling()) {
+ this.correctOverflow();
+ }
+ if (this.scrim) {
+ this.$.scrim.hide();
+ }
+ }
+ },
+ // Bounce back from overscroll region
+ correctOverflow: function() {
+ if(this.isInOverScroll()) {
+ var x = (this.scrollHorizontal) ? this.correctOverflowX() : false;
+ var y = (this.scrollVertical) ? this.correctOverflowY() : false;
+ if(x !== false && y !== false) {
+ this.scrollLeft = (x !== false) ? x : this.getScrollLeft();
+ this.scrollTop = (y !== false) ? y : this.getScrollTop();
+ this.startOverflowScrolling();
+ } else if(x !== false) {
+ this.scrollLeft = x;
+ this.scrollTop = this.targetScrollTop || this.scrollTop;
+ this.targetScrollLeft = this.getScrollLeft();
+ if(!this.vertical) {
+ this.startOverflowScrolling();
+ } else {
+ this.startScrolling();
+ }
+ } else if(y !== false) {
+ this.scrollTop = y;
+ this.scrollLeft = this.targetScrollLeft || this.scrollLeft;
+ this.targetScrollTop = this.getScrollTop();
+ if(!this.scrollHorizontal) {
+ this.startOverflowScrolling();
+ } else {
+ this.startScrolling();
+ }
+ }
+ }
+ },
+ // Determine if we're overscrolled on the x axis and if so return proper edge value
+ correctOverflowX: function() {
+ if(this.isInLeftOverScroll()) {
+ if(this.beyondBoundary(this.getScrollLeft(), this.leftBoundary, this.boundaryX)) {
+ return this.leftBoundary;
+ }
+ } else if(this.isInRightOverScroll()) {
+ if(this.beyondBoundary(this.getScrollLeft(), this.rightBoundary, this.boundaryX)) {
+ return -1*this.rightBoundary;
+ }
+ }
+ return false;
+ },
+ // Determine if we're overscrolled on the y axis and if so return proper edge value
+ correctOverflowY: function() {
+ if(this.isInTopOverScroll()) {
+ if(this.beyondBoundary(this.getScrollTop(), this.topBoundary, this.boundaryY)) {
+ return this.topBoundary;
+ }
+ } else if(this.isInBottomOverScroll()) {
+ if(this.beyondBoundary(this.getScrollTop(), this.bottomBoundary, this.boundaryY)) {
+ return -1*this.bottomBoundary;
+ }
+ }
+ return false;
+ },
+ // If we've crossed the determined delta, bounce back
+ beyondBoundary: function(current,boundary,max) {
+ return (Math.abs(Math.abs(boundary) - Math.abs(current)) > Math.abs(max));
+ },
+ // When user flicks/throws scroller, figure the distance to be travelled and whether we will end up
+ // in the overscroll region.
+ flick: function(inSender, e) {
+ if(this.dragging && this.flickOnEnabledAxis(e)) {
+ this.scrollLeft = this.scrollHorizontal ? this.calculateFlickDistance(this.scrollLeft, -1*e.xVelocity) : this.getScrollLeft();
+ this.scrollTop = this.scrollVertical ? this.calculateFlickDistance(this.scrollTop, -1*e.yVelocity) : this.getScrollTop();
+ this.targetScrollLeft = this.scrollLeft;
+ this.targetScrollTop = this.scrollTop;
+ this.boundaryX = null;
+ this.boundaryY = null;
+ // if flick will put the x axis into overscroll, figure where we should bounce back (boundary)
+ if(this.isInLeftOverScroll()) {
+ this.boundaryX = this.figureBoundary(this.getScrollLeft());
+ } else if(this.isInRightOverScroll()) {
+ this.boundaryX = this.figureBoundary(-1*this.bottomBoundary - this.getScrollLeft());
+ }
+ // if flick will put the y axis into overscroll, figure where we should bounce back (boundary)
+ if(this.isInTopOverScroll()) {
+ this.boundaryY = this.figureBoundary(this.getScrollTop());
+ } else if(this.isInBottomOverScroll()) {
+ this.boundaryY = this.figureBoundary(-1*this.bottomBoundary - this.getScrollTop());
+ }
+ // kickoff scrolling animation
+ this.startScrolling();
+ return this.preventDragPropagation;
+ }
+ },
+ flickOnEnabledAxis: function(e) {
+ return Math.abs(e.xVelocity) > Math.abs(e.yVelocity) ? this.scrollHorizontal : this.scrollVertical;
+ },
+ calculateFlickDistance: function(currentPosition, flickVelocity) {
+ return (currentPosition + (flickVelocity * this.kFlickScalar));
+ },
+ // Apply the 'scroll' transition, apply new transform based on x and y, and begin
+ // this.scrollInterval to update the scrollTop/Left values while scrolling
+ startScrolling: function() {
+ this.applyTransition("scroll");
+ this.effectScroll();
+ this.setCSSTransitionInterval();
+ this.scrolling = true;
+ },
+ // Apply the 'bounce' transition, apply new transform based on x and y, and begin
+ // this.scrollInterval to update the scrollTop/Left values while scrolling
+ startOverflowScrolling: function() {
+ this.applyTransition("bounce");
+ this.effectScroll();
+ this.setOverflowTransitionInterval();
+ this.scrolling = true;
+ },
+ // Apply the given transition to this.$.client
+ applyTransition: function(which) {
+ var transform = this.translation+": "+this.transitions[which];
+ this.$.client.applyStyle("-webkit-transition",this.transitions[which]);
+ },
+ // Turn off CSS transition and clear this.scrollInterval
+ stopScrolling: function() {
+ this.resetCSSTranslationVals();
+ this.clearCSSTransitionInterval();
+ this.scrolling = false;
+ },
+ // Create an interval to: update the x/y values while scrolling is happening, check for
+ // crossing into the overflow region, and bubble a scroll event
+ setCSSTransitionInterval: function() {
+ this.clearCSSTransitionInterval();
+ this.scrollInterval = setInterval(enyo.bind(this, function() {
+ this.updateScrollPosition();
+ this.correctOverflow();
+ }), this.scrollIntervalMS);
+ },
+ // Create an interval to: update the x/y values while scrolling is happening, and bubble
+ // a scroll event (don't check for crossing into overflow since we're there already)
+ setOverflowTransitionInterval: function() {
+ this.clearCSSTransitionInterval();
+ this.scrollInterval = setInterval(enyo.bind(this, function() {
+ this.updateScrollPosition();
+ }), this.scrollIntervalMS);
+ },
+ // Save current x/y position and bubble scroll event
+ updateScrollPosition: function() {
+ var yChanged = this.updateY();
+ var xChanged = this.updateX();
+ this.scroll();
+ if(!yChanged && !xChanged) {
+ this.stop();
+ }
+ },
+ // Clear this.scrollInterval
+ clearCSSTransitionInterval: function() {
+ if(this.scrollInterval) {
+ clearInterval(this.scrollInterval);
+ this.scrollInterval = null;
+ }
+ },
+ // Set scroller translation to current position and turn transition off. This effectively
+ // stops scrolling
+ resetCSSTranslationVals: function() {
+ var prop = enyo.dom.getCssTransformProp();
+ var transformStyle = window.getComputedStyle(this.$.client.node,null).getPropertyValue(prop).split('(')[1].split(')')[0].split(',');
+ this.applyTransition("none");
+ this.scrollLeft = -1*transformStyle[4];
+ this.scrollTop = -1*transformStyle[5];
+ this.effectScroll();
+ },
+ // Figure how far into the overscroll region we should go before bouncing back
+ figureBoundary: function(target) {
+ var absTarget = Math.abs(target);
+ var retVal = absTarget - absTarget/Math.pow(absTarget,0.02);
+ retVal = target < 0 ? -1*retVal : retVal;
+ return retVal;
+ },
+ // When transition animation is complete, check if we need to bounce back from overscroll
+ // region. If not, stop.
+ transitionComplete: function(inSender, inEvent) {
+ // Only process transition complete if sent from this container
+ if(inEvent.originator !== this.$.client) {
+ return;
+ }
+
+ var posChanged = false;
+
+ if(this.isInTopOverScroll()) {
+ posChanged = true;
+ this.scrollTop = this.topBoundary;
+ } else if (this.isInBottomOverScroll()) {
+ posChanged = true;
+ this.scrollTop = -1*this.bottomBoundary;
+ }
+
+ if(this.isInLeftOverScroll()) {
+ posChanged = true;
+ this.scrollLeft = this.leftBoundary;
+ } else if (this.isInRightOverScroll()) {
+ posChanged = true;
+ this.scrollLeft = -1*this.rightBoundary;
+ }
+
+ if(posChanged) {
+ this.startOverflowScrolling();
+ } else {
+ this.stop();
+ }
+ },
+ //* Scroll to the specified x and y coordinates
+ scrollTo: function(inX, inY) {
+ this.setScrollTop(inY);
+ this.setScrollLeft(inX);
+ this.start();
+ },
+ //* Returns the values of _overleft_ and _overtop_, if any.
+ getOverScrollBounds: function() {
+ return {
+ overleft: Math.min(this.leftBoundary + this.scrollLeft, 0) || Math.max(this.rightBoundary + this.scrollLeft, 0),
+ overtop: Math.min(this.topBoundary + this.scrollTop, 0) || Math.max(this.bottomBoundary + this.scrollTop, 0)
+ };
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchTranslateScrollStrategyjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/TranslateScrollStrategy.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/TranslateScrollStrategy.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/TranslateScrollStrategy.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,157 @@
</span><ins>+/**
+ _enyo.TranslateScrollStrategy_ is a helper kind that extends
+ <a href="#enyo.TouchScrollStrategy">enyo.TouchScrollStrategy</a>, optimizing
+ it for scrolling environments in which effecting scroll changes with
+ transforms is fastest.
+
+ _enyo.TranslateScrollStrategy_ is not typically created in application code.
+ Instead, it is specified as the value of the `strategyKind` property of an
+ `enyo.Scroller` or <a href="#enyo.List">enyo.List</a>, or is used by the
+ framework implicitly.
+*/
+enyo.kind({
+ name: "enyo.TranslateScrollStrategy",
+ kind: "TouchScrollStrategy",
+ //* Set to true to optimize the strategy to only use translation to scroll; this increases fluidity of
+ //* scrolling animation. It should not be used when the scroller contains controls that require keyboard
+ //* input. This is because when _translateOptimized_ is true, it is possible to position inputs such that
+ //* they will not become visibile when focused.
+ translateOptimized: false,
+ //* @protected
+ components: [
+ {name: "clientContainer", classes: "enyo-touch-scroller", components: [
+ {name: "client"}
+ ]}
+ ],
+ rendered: function() {
+ this.inherited(arguments);
+ enyo.makeBubble(this.$.clientContainer, "scroll");
+ },
+ getScrollSize: function() {
+ var n = this.$.client.hasNode();
+ return {width: n ? n.scrollWidth : 0, height: n ? n.scrollHeight : 0};
+ },
+ create: function() {
+ this.inherited(arguments);
+ // apply initial transform so we're always composited
+ enyo.dom.transformValue(this.$.client, this.translation, "0,0,0");
+ },
+ calcScrollNode: function() {
+ return this.$.clientContainer.hasNode();
+ },
+ maxHeightChanged: function() {
+ // content should cover scroller at a minimum if there's no max-height.
+ this.$.client.applyStyle("min-height", this.maxHeight ? null : "100%");
+ this.$.client.applyStyle("max-height", this.maxHeight);
+ this.$.clientContainer.addRemoveClass("enyo-scrollee-fit", !this.maxHeight);
+ },
+ shouldDrag: function(inSender, inEvent) {
+ // stop and update drag info before checking drag status
+ this.stop();
+ this.calcStartInfo();
+ return this.inherited(arguments);
+ },
+ syncScrollMath: function() {
+ if (!this.translateOptimized) {
+ this.inherited(arguments);
+ }
+ },
+ //* @public
+ //* Sets the left scroll position within the scroller.
+ setScrollLeft: function(inLeft) {
+ this.stop();
+ if (this.translateOptimized) {
+ var m = this.$.scrollMath;
+ m.setScrollX(-inLeft);
+ m.stabilize();
+ } else {
+ this.inherited(arguments);
+ }
+ },
+ //* Sets the top scroll position within the scroller.
+ setScrollTop: function(inTop) {
+ this.stop();
+ if (this.translateOptimized) {
+ var m = this.$.scrollMath;
+ m.setScrollY(-inTop);
+ m.stabilize();
+ } else {
+ this.inherited(arguments);
+ }
+ },
+ //* Gets the left scroll position within the scroller.
+ getScrollLeft: function() {
+ return this.translateOptimized ? this.scrollLeft: this.inherited(arguments);
+ },
+ //* Gets the top scroll position within the scroller.
+ getScrollTop: function() {
+ return this.translateOptimized ? this.scrollTop : this.inherited(arguments);
+ },
+ //* @protected
+ scrollMathStart: function(inSender) {
+ this.inherited(arguments);
+ this.scrollStarting = true;
+ this.startX = 0;
+ this.startY = 0;
+ if (!this.translateOptimized && this.scrollNode) {
+ this.startX = this.getScrollLeft();
+ this.startY = this.getScrollTop();
+ }
+ },
+ scrollMathScroll: function(inSender) {
+ if(!this.overscroll) { //don't overscroll past edges
+ this.scrollLeft = -Math.min(inSender.leftBoundary, Math.max(inSender.rightBoundary, inSender.x));
+ this.scrollTop = -Math.min(inSender.topBoundary, Math.max(inSender.bottomBoundary, inSender.y));
+ } else {
+ this.scrollLeft = -inSender.x;
+ this.scrollTop = -inSender.y;
+ }
+ if (this.isScrolling()) {
+ if (this.$.scrollMath.isScrolling()) {
+ this.effectScroll(this.startX - this.scrollLeft, this.startY - this.scrollTop);
+ }
+ if (this.thumb) {
+ this.updateThumbs();
+ }
+ }
+ },
+ // While moving, scroller uses translate.
+ effectScroll: function(inX, inY) {
+ var o = inX + "px, " + inY + "px" + (this.accel ? ",0" : "");
+ enyo.dom.transformValue(this.$.client, this.translation, o);
+ },
+ // When stopped, we use scrollLeft/Top (makes cursor positioning automagic).
+ effectScrollStop: function() {
+ if (!this.translateOptimized) {
+ var t = "0,0" + (this.accel ? ",0" : "");
+ // FIXME: normally translate3d changes not effect scrollHeight; however
+ // there appear to be some dom changes (e.g. showing a node inside the scroller,
+ // which do cause the scrollHeight to be changed from the translate3d.
+ // In this case setting the translate3d back to 0 does not restore scrollHeight.
+ // This causes a problem because setting scrollTop can produced an unexpected result if
+ // scrollHeight is less than expected.
+ // We detect this fault by validating scroll bounds and (1) un-apply the translate3d,
+ // (2) update scrollTop/Left, and (3) re-apply a 0,0,0 translate3d to ensure compositing.
+ // Luckily this corrects the problem (which appears to be a webkit bug). Note that
+ // it's important to maintain a composited state (translate3d 0,0,0) or Android 4 is
+ // slow to start scrolling.
+ var m = this.$.scrollMath, sb = this._getScrollBounds();
+ var needsBoundsFix = Boolean((sb.maxTop + m.bottomBoundary) || (sb.maxLeft + m.rightBoundary));
+ enyo.dom.transformValue(this.$.client, this.translation, needsBoundsFix ? null : t);
+ // note: this asynchronously triggers dom scroll event
+ this.setScrollLeft(this.scrollLeft);
+ this.setScrollTop(this.scrollTop);
+ if (needsBoundsFix) {
+ enyo.dom.transformValue(this.$.client, this.translation, t);
+ }
+ }
+ },
+ // FIXME: we can fix scrolling artifacts BUGS on Android 4.04 with this heinous incantation.
+ twiddle: function() {
+ if (this.translateOptimized && this.scrollNode) { // this.scrollNode is not always defined and makes Motorola XOOM crash
+ this.scrollNode.scrollTop = 1;
+ this.scrollNode.scrollTop = 0;
+ }
+ },
+ down: enyo.nop
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchgesturejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/gesture.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/gesture.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/gesture.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,130 @@
</span><ins>+/**
+ Gesture events: emulates iOS gesture events on non iOS devices
+ Event Contents
+ - pageX / pageY: center point between fingers
+ - rotation: degrees of rotation from beginning of gesture
+ - scale: % change of distance between fingers
+*/
+//* @protected
+(function() {
+ if (!enyo.platform.gesture && enyo.platform.touch) {
+ enyo.dispatcher.features.push(function(e) {
+ if (handlers[e.type]) {
+ touchGestures[e.type](e);
+ }
+ });
+ }
+ var handlers = {
+ touchstart: true,
+ touchmove: true,
+ touchend: true
+ };
+ var touchGestures = {
+ orderedTouches: [],
+ gesture: null,
+ touchstart: function(inEvent) {
+ // some devices can send multiple changed touches on start and end
+ enyo.forEach(inEvent.changedTouches, function(t) {
+ var id = t.identifier;
+ // some devices can send multiple touchstarts
+ if (enyo.indexOf(id, this.orderedTouches) < 0) {
+ this.orderedTouches.push(id);
+ }
+ }, this);
+ if (inEvent.touches.length >= 2 && !this.gesture) {
+ var p = this.gesturePositions(inEvent);
+ this.gesture = this.gestureVector(p);
+ this.gesture.angle = this.gestureAngle(p);
+ this.gesture.scale = 1;
+ this.gesture.rotation = 0;
+ var g = this.makeGesture("gesturestart", inEvent, {vector: this.gesture, scale: 1, rotation: 0});
+ enyo.dispatch(g);
+ }
+ },
+ touchend: function(inEvent) {
+ // some devices can send multiple changed touches on start and end
+ enyo.forEach(inEvent.changedTouches, function(t) {
+ enyo.remove(t.identifier, this.orderedTouches);
+ }, this);
+ if (inEvent.touches.length <= 1 && this.gesture) {
+ var t = inEvent.touches[0] || inEvent.changedTouches[inEvent.changedTouches.length - 1];
+ // gesture end sends last rotation and scale, with the x/y of the last finger
+ enyo.dispatch(this.makeGesture("gestureend", inEvent, {vector: {xcenter: t.pageX, ycenter: t.pageY}, scale: this.gesture.scale, rotation: this.gesture.rotation}));
+ this.gesture = null;
+ }
+ },
+ touchmove: function(inEvent) {
+ if (this.gesture) {
+ var g = this.makeGesture("gesturechange", inEvent);
+ this.gesture.scale = g.scale;
+ this.gesture.rotation = g.rotation;
+ enyo.dispatch(g);
+ }
+ },
+ findIdentifiedTouch: function(inTouches, inId) {
+ for (var i = 0, t; (t = inTouches[i]); i++) {
+ if (t.identifier === inId) {
+ return t;
+ }
+ }
+ },
+ gesturePositions: function(inEvent) {
+ var first = this.findIdentifiedTouch(inEvent.touches, this.orderedTouches[0]);
+ var last = this.findIdentifiedTouch(inEvent.touches, this.orderedTouches[this.orderedTouches.length - 1]);
+ var fx = first.pageX, lx = last.pageX, fy = first.pageY, ly = last.pageY;
+ // center the first touch as 0,0
+ var x = lx - fx, y = ly - fy;
+ var h = Math.sqrt(x*x + y*y);
+ return {x: x, y: y, h: h, fx: fx, lx: lx, fy: fy, ly: ly};
+ },
+ // find rotation angle
+ gestureAngle: function(inPositions) {
+ var p = inPositions;
+ // yay math!, rad -> deg
+ var a = Math.asin(p.y / p.h) * (180 / Math.PI);
+ // fix for range limits of asin (-90 to 90)
+ // Quadrants II and III
+ if (p.x < 0) {
+ a = 180 - a;
+ }
+ // Quadrant IV
+ if (p.x > 0 && p.y < 0) {
+ a += 360;
+ }
+ return a;
+ },
+ // find bounding box
+ gestureVector: function(inPositions) {
+ // the least recent touch and the most recent touch determine the bounding box of the gesture event
+ var p = inPositions;
+ // center the first touch as 0,0
+ return {
+ magnitude: p.h,
+ xcenter: Math.abs(Math.round(p.fx + (p.x / 2))),
+ ycenter: Math.abs(Math.round(p.fy + (p.y / 2)))
+ };
+ },
+ makeGesture: function(inType, inEvent, inCache) {
+ var vector, scale, rotation;
+ if (inCache) {
+ vector = inCache.vector;
+ scale = inCache.scale;
+ rotation = inCache.rotation;
+ } else {
+ var p = this.gesturePositions(inEvent);
+ vector = this.gestureVector(p);
+ scale = vector.magnitude / this.gesture.magnitude;
+ // gestureEvent.rotation is difference from the starting angle, clockwise
+ rotation = (360 + this.gestureAngle(p) - this.gesture.angle) % 360;
+ }
+ var e = enyo.clone(inEvent);
+ return enyo.mixin(e, {
+ type: inType,
+ scale: scale,
+ pageX: vector.xcenter,
+ pageY: vector.ycenter,
+ rotation: rotation
+ });
+ }
+ };
+})();
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchmseventsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/msevents.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/msevents.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/msevents.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,93 @@
</span><ins>+//* @protected
+(function() {
+ // add touch-specific gesture feature
+ var gesture = enyo.gesture;
+ if (window.navigator.msPointerEnabled) {
+ var msEvents = [
+ "MSPointerDown",
+ "MSPointerUp",
+ "MSPointerMove",
+ "MSPointerOver",
+ "MSPointerOut",
+ "MSPointerCancel",
+ "MSGestureTap",
+ "MSGestureDoubleTap",
+ "MSGestureHold",
+ "MSGestureStart",
+ "MSGestureChange",
+ "MSGestureEnd"
+ ];
+ enyo.forEach(msEvents, function(e) {
+ enyo.dispatcher.listen(document, e);
+ });
+ // add our own MSPointer event handler
+ enyo.dispatcher.features.push(function(e) {
+ if (handlers[e.type] && e.isPrimary) {
+ handlers[e.type](e);
+ }
+ });
+ // remove the default mouse event handlers
+ enyo.gesture.events = {};
+ }
+
+ var gestureNormalize = function(inType, inEvent) {
+ var e = enyo.clone(inEvent);
+ return enyo.mixin(e, {
+ pageX: inEvent.translationX || 0,
+ pageY: inEvent.translationY || 0,
+ // rad -> deg
+ rotation: (inEvent.rotation * (180 / Math.PI)) || 0,
+ type: inType,
+ srcEvent: inEvent,
+ preventDefault: gesture.preventDefault,
+ disablePrevention: gesture.disablePrevention
+ });
+ };
+ var makeEvent = function(inEvent) {
+ var e = enyo.clone(inEvent);
+ e.srcEvent = inEvent;
+ // normalize "mouse button" info
+ e.which = 1;
+ return e;
+ };
+
+ var handlers = {
+ // FIXME: need to register for gestures in MSPointerDown
+ // according to Microsoft docs
+ /*MSGestureStart: function(inEvent) {
+ enyo.dispatch(gestureNormalize("gesturestart", inEvent));
+ },
+ MSGestureChange: function(inEvent) {
+ enyo.dispatch(gestureNormalize("gesturechange", inEvent));
+ },
+ MSGestureEnd: function(inEvent) {
+ enyo.dispatch(gestureNormalize("gestureend", inEvent));
+ },*/
+ MSPointerDown: function(inEvent) {
+ var e = makeEvent(inEvent);
+ gesture.down(e);
+ },
+ MSPointerUp: function(inEvent) {
+ var e = makeEvent(inEvent);
+ gesture.up(e);
+ },
+ MSPointerMove: function(inEvent) {
+ var e = makeEvent(inEvent);
+ gesture.move(e);
+ },
+ MSPointerCancel: function(inEvent) {
+ // FIXME: not really the same as touchend, as touch action
+ // was cancelled, but Enyo doesn't have that concept
+ var e = makeEvent(inEvent);
+ gesture.up(e);
+ },
+ MSPointerOver: function(inEvent) {
+ var e = makeEvent(inEvent);
+ gesture.over(e);
+ },
+ MSPointerOut: function(inEvent) {
+ var e = makeEvent(inEvent);
+ gesture.out(e);
+ }
+ };
+})();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchpackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+enyo.depends(
+ "touch.js",
+ "msevents.js",
+ "gesture.js",
+ "ScrollMath.js",
+ "ScrollStrategy.js",
+ "Thumb.css",
+ "Thumb.js",
+ "TouchScrollStrategy.js",
+ "TranslateScrollStrategy.js",
+ "TransitionScrollStrategy.js",
+ "Scroller.js",
+ "Scroller.css"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourcetouchtouchjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/touch/touch.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/touch/touch.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/touch/touch.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,139 @@
</span><ins>+//* @protected
+enyo.requiresWindow(function() {
+ // add touch-specific gesture feature
+ var gesture = enyo.gesture;
+ var oldevents = gesture.events;
+ //
+ gesture.events.touchstart = function(e) {
+ // for duration of this touch, only handle touch events. Old event
+ // structure will be restored during touchend.
+ gesture.events = touchGesture;
+ gesture.events.touchstart(e);
+ };
+ //
+ var touchGesture = {
+ _touchCount: 0,
+ touchstart: function(inEvent) {
+ this._touchCount += inEvent.changedTouches.length;
+ this.excludedTarget = null;
+ var e = this.makeEvent(inEvent);
+ gesture.down(e);
+ // generate a new event object since over is a different event
+ e = this.makeEvent(inEvent);
+ this.overEvent = e;
+ gesture.over(e);
+ },
+ touchmove: function(inEvent) {
+ enyo.job.stop("resetGestureEvents");
+ // NOTE: allow user to supply a node to exclude from event
+ // target finding via the drag event.
+ var de = gesture.drag.dragEvent;
+ this.excludedTarget = de && de.dragInfo && de.dragInfo.node;
+ var e = this.makeEvent(inEvent);
+ gesture.move(e);
+ // prevent default document scrolling if enyo.bodyIsFitting == true
+ // avoid window scrolling by preventing default on this event
+ // note: this event can be made unpreventable (native scrollers do this)
+ if (enyo.bodyIsFitting) {
+ inEvent.preventDefault();
+ }
+ // synthesize over and out (normally generated via mouseout)
+ if (this.overEvent && this.overEvent.target != e.target) {
+ this.overEvent.relatedTarget = e.target;
+ e.relatedTarget = this.overEvent.target;
+ gesture.out(this.overEvent);
+ gesture.over(e);
+ }
+ this.overEvent = e;
+ },
+ touchend: function(inEvent) {
+ gesture.up(this.makeEvent(inEvent));
+ // NOTE: in touch land, there is no distinction between
+ // a pointer enter/leave and a drag over/out.
+ // While it may make sense to send a leave event when a touch
+ // ends, it does not make sense to send a dragout.
+ // We avoid this by processing out after up, but
+ // this ordering is ad hoc.
+ gesture.out(this.overEvent);
+ // reset the event handlers back to the mouse-friendly ones after
+ // a short timeout. We can't do this directly in this handler
+ // because it messes up Android to handle the mouseup event.
+ // FIXME: for 2.1 release, conditional on platform being
+ // desktop Chrome, since we're seeing issues in PhoneGap with this
+ // code.
+ this._touchCount -= inEvent.changedTouches.length;
+ },
+ // use mouseup after touches are done to reset event handling back to default
+ // --this works as long as no one did a preventDefault on the touch events
+ mouseup: function(e) {
+ if (this._touchCount === 0) {
+ this.sawMousedown = false;
+ gesture.events = oldevents;
+ }
+ },
+ makeEvent: function(inEvent) {
+ var e = enyo.clone(inEvent.changedTouches[0]);
+ e.srcEvent = inEvent;
+ e.target = this.findTarget(e);
+ // normalize "mouse button" info
+ e.which = 1;
+ //enyo.log("target for " + inEvent.type + " at " + e.pageX + ", " + e.pageY + " is " + (e.target ? e.target.id : "none"));
+ return e;
+ },
+ calcNodeOffset: function(inNode) {
+ if (inNode.getBoundingClientRect) {
+ var o = inNode.getBoundingClientRect();
+ return {
+ left: o.left,
+ top: o.top,
+ width: o.width,
+ height: o.height
+ };
+ }
+ },
+ findTarget: function(e) {
+ return document.elementFromPoint(e.clientX, e.clientY);
+ },
+ // NOTE: will find only 1 element under the touch and
+ // will fail if an element is positioned outside the bounding box of its parent
+ findTargetTraverse: function(inNode, inX, inY) {
+ var n = inNode || document.body;
+ var o = this.calcNodeOffset(n);
+ if (o && n != this.excludedTarget) {
+ var x = inX - o.left;
+ var y = inY - o.top;
+ //enyo.log("test: " + n.id + " (left: " + o.left + ", top: " + o.top + ", width: " + o.width + ", height: " + o.height + ")");
+ if (x>0 && y>0 && x<=o.width && y<=o.height) {
+ //enyo.log("IN: " + n.id + " -> [" + x + "," + y + " in " + o.width + "x" + o.height + "] (children: " + n.childNodes.length + ")");
+ var target;
+ for (var n$=n.childNodes, i=n$.length-1, c; (c=n$[i]); i--) {
+ target = this.findTargetTraverse(c, inX, inY);
+ if (target) {
+ return target;
+ }
+ }
+ return n;
+ }
+ }
+ },
+ connect: function() {
+ enyo.forEach(['ontouchstart', 'ontouchmove', 'ontouchend', 'ongesturestart', 'ongesturechange', 'ongestureend'], function(e) {
+ document[e] = enyo.dispatch;
+ });
+ if (enyo.platform.androidChrome <= 18 || enyo.platform.silk === 2) {
+ // HACK: on Chrome for Android v18 on devices with higher density displays,
+ // document.elementFromPoint expects screen coordinates, not document ones
+ // bug also appears on Kindle Fire HD
+ this.findTarget = function(e) {
+ return document.elementFromPoint(e.screenX, e.screenY);
+ };
+ } else if (!document.elementFromPoint) {
+ this.findTarget = function(e) {
+ return this.findTargetTraverse(null, e.clientX, e.clientY);
+ };
+ }
+ }
+ };
+ //
+ touchGesture.connect();
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiAnimatorjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/Animator.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/Animator.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/Animator.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,132 @@
</span><ins>+/**
+ _enyo.Animator_ is a basic animation component. Call _play_ to start the
+ animation. The animation will run for the period (in milliseconds) specified
+ by its _duration_ property. The _onStep_ event will fire in quick
+ succession and should be handled to do something based on the _value_
+ property.
+
+ The _value_ property will progress from _startValue_ to _endValue_ during
+ the animation based on the function referenced by the _easingFunction_
+ property. The _stop_ method may be called to manually stop an in-progress
+ animation; calling it will fire the _onStop_ event. When an animation
+ completes normally, the _onEnd_ event is fired.
+
+ Event handlers may be specified as functions. If specified, the handler
+ function will be used to handle the event directly, without sending the
+ event to its owner or bubbling it. The _context_ property can be used to
+ call the supplied event functions in a particular "this" context.
+*/
+enyo.kind({
+ name: "enyo.Animator",
+ kind: "Component",
+ published: {
+ //* Animation duration in milliseconds
+ duration: 350,
+ //* Value of _value_ property at the beginning of an animation
+ startValue: 0,
+ //* Value of _value_ property at the end of an animation
+ endValue: 1,
+ //* Node that must be visible in order for the animation to continue.
+ //* This reference is destroyed when the animation ceases.
+ node: null,
+ //* Function that determines how the animation progresses from
+ //* _startValue_ to _endValue_
+ easingFunction: enyo.easing.cubicOut
+ },
+ events: {
+ //* Fires when an animation step occurs.
+ onStep: "",
+ //* Fires when the animation finishes normally.
+ onEnd: "",
+ //* Fires when the animation is prematurely stopped.
+ onStop: ""
+ },
+ //* @protected
+ constructed: function() {
+ this.inherited(arguments);
+ this._next = enyo.bind(this, "next");
+ },
+ destroy: function() {
+ this.stop();
+ this.inherited(arguments);
+ },
+ //* @public
+ //* Plays the animation.
+ //* For convenience, _inProps_ will be mixed directly into this object.
+ play: function(inProps) {
+ this.stop();
+ this.reversed = false;
+ if (inProps) {
+ enyo.mixin(this, inProps);
+ }
+ this.t0 = this.t1 = enyo.now();
+ this.value = this.startValue;
+ this.job = true;
+ this.next();
+ return this;
+ },
+ //* Stops the animation and fires the _onStop_ event.
+ stop: function() {
+ if (this.isAnimating()) {
+ this.cancel();
+ this.fire("onStop");
+ return this;
+ }
+ },
+ //* Reverses the direction of a running animation; returns self if animating.
+ reverse: function() {
+ if (this.isAnimating()) {
+ this.reversed = !this.reversed;
+ var now = this.t1 = enyo.now();
+ // adjust start time (t0) to allow for animation done so far to replay
+ var elapsed = now - this.t0;
+ this.t0 = now + elapsed - this.duration;
+ // swap start and end values
+ var startValue = this.startValue;
+ this.startValue = this.endValue;
+ this.endValue = startValue;
+ return this;
+ }
+ },
+ //* Returns true if animation is in progress.
+ isAnimating: function() {
+ return Boolean(this.job);
+ },
+ //* @protected
+ requestNext: function() {
+ this.job = enyo.requestAnimationFrame(this._next, this.node);
+ },
+ cancel: function() {
+ enyo.cancelRequestAnimationFrame(this.job);
+ this.node = null;
+ this.job = null;
+ },
+ shouldEnd: function() {
+ return (this.dt >= this.duration);
+ },
+ next: function() {
+ this.t1 = enyo.now();
+ this.dt = this.t1 - this.t0;
+ // time independent
+ var f = this.fraction = enyo.easedLerp(this.t0, this.duration, this.easingFunction, this.reversed);
+ this.value = this.startValue + f * (this.endValue - this.startValue);
+ if (f >= 1 || this.shouldEnd()) {
+ this.value = this.endValue;
+ this.fraction = 1;
+ this.fire("onStep");
+ this.fire("onEnd");
+ this.cancel();
+ } else {
+ this.fire("onStep");
+ this.requestNext();
+ }
+ },
+ fire: function(inEventName) {
+ var fn = this[inEventName];
+ if (enyo.isString(fn)) {
+ this.bubble(inEventName);
+ } else if (fn) {
+ fn.call(this.context || window, this);
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiBaseLayoutjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/BaseLayout.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/BaseLayout.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/BaseLayout.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+/**
+ _enyo.BaseLayout_ provides a basic layout strategy, positioning contained
+ components with the _enyo-positioned_ layoutClass. In addition, it adjusts
+ the layout when _reflow_ is called, removing or adding the _enyo-fit_ class
+ for components that have set the _fit_ property.
+*/
+enyo.kind({
+ name: "enyo.BaseLayout",
+ kind: enyo.Layout,
+ layoutClass: "enyo-positioned",
+ //* Adds or removes the _enyo-fit_ class for components whose _fit_ property
+ //* has been set.
+ reflow: function() {
+ enyo.forEach(this.container.children, function(c) {
+ if (c.fit !== null) {
+ c.addRemoveClass("enyo-fit", c.fit);
+ }
+ }, this);
+ }
+});
+
+//enyo.Control.prototype.layoutKind = "enyo.BaseLayout";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiButtonjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/Button.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/Button.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/Button.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+/**
+ _enyo.Button_ implements an HTML button, with support for grouping using
+ <a href="#enyo.Group">enyo.Group</a>.
+
+ For more information, see the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Buttons">Buttons</a> in the
+ Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.Button",
+ //* @protected
+ kind: enyo.ToolDecorator,
+ tag: "button",
+ attributes: {
+ // set to button, as default is "submit" which can cause unexpected
+ // problems when controls are used inside a form
+ type: "button"
+ },
+ //* @public
+ published: {
+ //* When true, button is shown as disabled and does not generate tap
+ //* events
+ disabled: false
+ },
+ //* @protected
+ create: function() {
+ this.inherited(arguments);
+ this.disabledChanged();
+ },
+ disabledChanged: function() {
+ this.setAttribute("disabled", this.disabled);
+ },
+ tap: function() {
+ if (this.disabled) {
+ // work around for platforms like Chrome on Android or Opera that send
+ // mouseup to disabled form controls
+ return true;
+ } else {
+ this.setActive(true);
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiCheckboxjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/Checkbox.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/Checkbox.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/Checkbox.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,77 @@
</span><ins>+/**
+ _enyo.Checkbox_ implements an HTML checkbox input, with support for grouping.
+*/
+enyo.kind({
+ name: "enyo.Checkbox",
+ kind: enyo.Input,
+ classes: "enyo-checkbox",
+ events: {
+ //* Fires when checkbox is tapped.
+ onActivate: ""
+ },
+ published: {
+ //* Value of checkbox; true if checked
+ checked: false,
+ //* Group API requirement for determining selected item
+ active: false,
+ //* @protected
+ type: "checkbox"
+ },
+ //* @protected
+ // disable classes inherited from enyo.Input
+ kindClasses: "",
+ handlers: {
+ onchange: "change",
+ onclick: "click"
+ },
+ create: function() {
+ this.inherited(arguments);
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ if (this.active) {
+ this.activeChanged();
+ }
+ this.checkedChanged();
+ },
+ // instance 'checked' property is linked to DOM 'checked' property
+ getChecked: function() {
+ return enyo.isTrue(this.getNodeProperty("checked", this.checked));
+ },
+ checkedChanged: function() {
+ this.setNodeProperty("checked", this.checked);
+ this.setAttribute("checked", this.checked ? "checked" : "");
+ this.setActive(this.checked);
+ },
+ // active property, and onActivate event, are part of "GroupItem" interface
+ // that we support in this object
+ activeChanged: function() {
+ this.active = enyo.isTrue(this.active);
+ this.setChecked(this.active);
+ this.bubble("onActivate");
+ },
+ // all input type controls support 'value' property
+ setValue: function(inValue) {
+ this.setChecked(enyo.isTrue(inValue));
+ },
+ getValue: function() {
+ return this.getChecked();
+ },
+ valueChanged: function() {
+ // inherited behavior is to set "value" attribute and node-property
+ // which does not apply to checkbox (uses "checked") so
+ // we squelch the inherited method
+ },
+ change: function() {
+ this.setActive(this.getChecked());
+ },
+ click: function(inSender, inEvent) {
+ // Various versions of IE (notably IE8) do not fire 'onchange' for
+ // checkboxes, so we discern change via 'click'.
+ // Note: keyboard interaction (e.g. pressing space when focused) fires
+ // a click event.
+ if (enyo.platform.ie <= 8) {
+ this.bubble("onchange", inEvent);
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiDragAvatarjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/DragAvatar.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/DragAvatar.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/DragAvatar.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,90 @@
</span><ins>+//* @protected
+enyo.kind({
+ name: "enyo._DragAvatar",
+ style: "position: absolute; z-index: 10; pointer-events: none; cursor: move;",
+ showing: false,
+ showingChanged: function() {
+ this.inherited(arguments);
+ document.body.style.cursor = this.showing ? "move" : null;
+ }
+});
+
+//* @public
+/**
+ _enyo.DragAvatar_ creates a control to follow the pointer when dragging. It
+ automatically displays the avatar control when the user drags, and updates
+ its position relative to the current pointer location.
+
+ enyo.kind({
+ name: "App",
+ handlers: {
+ ondrag: "drag",
+ ondragfinish: "dragFinish",
+ },
+ components: [
+ {name:"dragAvatar", kind:"DragAvatar",
+ components: [{tag: "img", src: "images/icon.png"}]
+ }
+ ],
+ drag: function(inSender, inEvent) {
+ this.$.dragAvatar.drag(inEvent);
+ },
+ dragFinish: function(inSender, inEvent) {
+ this.$.dragAvatar.hide();
+ }
+ });
+*/
+enyo.kind({
+ name: "enyo.DragAvatar",
+ kind: enyo.Component,
+ published: {
+ //* Current visibility state of the DragAvatar
+ showing: false,
+ /**
+ Distance (in pixels) along the horizontal axis between the current
+ drag position and where the avatar control is displayed.
+ */
+ offsetX: 20,
+ /**
+ Distance (in pixels) along the vertical axis between the current
+ drag position and where the avatar control is displayed.
+ */
+ offsetY: 30
+ },
+ //* @protected
+ initComponents: function() {
+ this.avatarComponents = this.components;
+ this.components = null;
+ this.inherited(arguments);
+ },
+ requireAvatar: function() {
+ // FIXME: there is nobody to call teardownRender on this.avatar
+ // if document.body.innerHTML has been written over, his node is invalid
+ // we should have a trap for this condition here
+ if (!this.avatar) {
+ this.avatar = this.createComponent({kind: enyo._DragAvatar, parentNode: document.body, showing: false, components: this.avatarComponents}).render();
+ }
+ },
+ showingChanged: function() {
+ this.avatar.setShowing(this.showing);
+ document.body.style.cursor = this.showing ? "move" : null;
+ },
+ //* @public
+ /**
+ Instantiates the avatar control (if necessary), determines correct
+ position, and calls _show_ to make it visible.
+ */
+ drag: function(inEvent) {
+ this.requireAvatar();
+ this.avatar.setBounds({top: inEvent.pageY - this.offsetY, left: inEvent.pageX + this.offsetX});
+ this.show();
+ },
+ //* Shows the DragAvatar.
+ show: function() {
+ this.setShowing(true);
+ },
+ //* Hides the DragAvatar.
+ hide: function() {
+ this.setShowing(false);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiFloatingLayerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/FloatingLayer.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/FloatingLayer.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/FloatingLayer.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+/**
+ _enyo.FloatingLayer_ is a control that provides a layer for controls that
+ should be displayed above an application.
+ The FloatingLayer singleton can be set as a control's parent to have the
+ control float above an application, e.g.:
+
+ create: function() {
+ this.inherited(arguments);
+ this.setParent(enyo.floatingLayer);
+ }
+
+ Note: It's not intended that users create instances of _enyo.FloatingLayer_.
+*/
+//* @protected
+enyo.kind({
+ name: "enyo.FloatingLayer",
+ //* @protected
+ create: function() {
+ this.inherited(arguments);
+ this.setParent(null);
+ },
+ render: function() {
+ this.parentNode = document.body;
+ return this.inherited(arguments);
+ },
+ generateInnerHtml: function() {
+ return "";
+ },
+ beforeChildRender: function() {
+ if (!this.hasNode()) {
+ this.render();
+ }
+ },
+ teardownChildren: function() {
+ }
+});
+
+enyo.floatingLayer = new enyo.FloatingLayer();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiGroupjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/Group.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/Group.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/Group.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+/**
+ _enyo.Group_ provides a wrapper around multiple elements. It enables the
+ creation of radio groups from arbitrary components supporting the
+ [GroupItem](#enyo.GroupItem) API.
+*/
+enyo.kind({
+ name: "enyo.Group",
+ published: {
+ /**
+ If true, only one GroupItem in the component list may be active at
+ a given time.
+ */
+ highlander: true,
+ //* The control that was last selected
+ active: null
+ },
+ //* @protected
+ handlers: {
+ onActivate: "activate"
+ },
+ activate: function(inSender, inEvent) {
+ if (this.highlander) {
+ // deactivation messages are ignored unless it's an attempt
+ // to deactivate the highlander
+ if (!inEvent.originator.active) {
+ // this clause prevents deactivating a grouped item once it's been active.
+ // the only proper way to deactivate a grouped item is to choose a new
+ // highlander.
+ if (inEvent.originator == this.active) {
+ this.active.setActive(true);
+ }
+ } else {
+ this.setActive(inEvent.originator);
+ }
+ }
+ },
+ activeChanged: function(inOld) {
+ if (inOld) {
+ inOld.setActive(false);
+ inOld.removeClass("active");
+ }
+ if (this.active) {
+ this.active.addClass("active");
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiGroupItemjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/GroupItem.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/GroupItem.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/GroupItem.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+/**
+ _enyo.GroupItem_ is the base kind for the Grouping API. It manages the
+ active state of the component (or the inheriting component). A subkind may
+ call _setActive_ to set the _active_ property to the desired state; this
+ will additionally bubble an _onActivate_ event, which can be handled as
+ needed by the containing components. This is useful for creating groups of
+ items whose state should be managed as a group.
+
+ For an example of how this works, see the
+ <a href="#enyo.Group">enyo.Group</a> kind, which enables the creation of
+ radio groups from arbitrary components that support the Grouping API.
+*/
+
+enyo.kind({
+ name: "enyo.GroupItem",
+ published: {
+ //* True if the item is currently selected
+ active: false
+ },
+ //* @protected
+ rendered: function() {
+ this.inherited(arguments);
+ this.activeChanged();
+ },
+ activeChanged: function() {
+ this.bubble("onActivate");
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiImagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/Image.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/Image.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/Image.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+/**
+ _enyo.Image_ implements an HTML <img> element and, optionally, bubbles
+ the _onload_ and _onerror_ events. Image dragging is suppressed by default,
+ so as not to interfere with touch interfaces.
+*/
+enyo.kind({
+ name: "enyo.Image",
+ //* When true, no _onload_ or _onerror_ event handlers will be created
+ noEvents: false,
+ //* @protected
+ tag: "img",
+ attributes: {
+ // note: draggable attribute takes one of these String values: "true", "false", "auto"
+ // (Boolean _false_ would remove the attribute)
+ draggable: "false"
+ },
+ create: function() {
+ if (this.noEvents) {
+ delete this.attributes.onload;
+ delete this.attributes.onerror;
+ }
+ this.inherited(arguments);
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ enyo.makeBubble(this, "load", "error");
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiInputjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/Input.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/Input.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/Input.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,148 @@
</span><ins>+/**
+ _enyo.Input_ implements an HTML <input> element with cross-platform
+ support for change events.
+
+ You can listen for _oninput_ and _onchange_ DOM events from this control
+ to know when the text inside has been modified. _oninput_ fires immediately,
+ while _onchange_ fires when the text has changed and the input subsequently
+ loses focus.
+
+ For more information, see the documentation on
+ [Text Fields](https://github.com/enyojs/enyo/wiki/Text-Fields) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.Input",
+ published: {
+ /**
+ Value of the input. Use this property only to initialize the value.
+ Call _getValue_ and _setValue_ to manipulate the value at runtime.
+ */
+ value: "",
+ //* Text to display when the input is empty
+ placeholder: "",
+ /**
+ Type of input; if not specified, it's treated as "text". It can
+ be anything specified for the _type_ attribute in the HTML
+ specification, including "url", "email", "search", or "number".
+ */
+ type: "",
+ /**
+ When true, prevents input into the control. This maps to the
+ _disabled_ DOM attribute.
+ */
+ disabled: false,
+ //* When true, select the contents of the input when it gains focus.
+ selectOnFocus: false
+ },
+ events: {
+ //* Fires when the input is disabled or enabled.
+ onDisabledChange: ""
+ },
+ //* Set to true to focus this control when it is rendered
+ defaultFocus: false,
+ //* @protected
+ tag: "input",
+ classes: "enyo-input",
+ handlers: {
+ onfocus: "focused",
+ oninput: "input",
+ onclear: "clear",
+ ondragstart: "dragstart"
+ },
+ create: function() {
+ if (enyo.platform.ie) {
+ this.handlers.onkeyup = "iekeyup";
+ }
+ if (enyo.platform.windowsPhone) {
+ this.handlers.onkeydown = "iekeydown";
+ }
+ this.inherited(arguments);
+ this.placeholderChanged();
+ // prevent overriding a custom attribute with null
+ if (this.type) {
+ this.typeChanged();
+ }
+ this.valueChanged();
+ },
+ rendered: function() {
+ this.inherited(arguments);
+
+ enyo.makeBubble(this, "focus", "blur");
+
+ //Force onchange event to be bubbled inside Enyo for IE8
+ if(enyo.platform.ie == 8){
+ this.setAttribute("onchange", enyo.bubbler);
+ }
+
+ this.disabledChanged();
+ if (this.defaultFocus) {
+ this.focus();
+ }
+ },
+ typeChanged: function() {
+ this.setAttribute("type", this.type);
+ },
+ placeholderChanged: function() {
+ this.setAttribute("placeholder", this.placeholder);
+ },
+ disabledChanged: function() {
+ this.setAttribute("disabled", this.disabled);
+ this.bubble("onDisabledChange");
+ },
+ getValue: function() {
+ return this.getNodeProperty("value", this.value);
+ },
+ valueChanged: function() {
+ this.setAttribute("value", this.value);
+ this.setNodeProperty("value", this.value);
+ },
+ iekeyup: function(inSender, inEvent) {
+ var ie = enyo.platform.ie, kc = inEvent.keyCode;
+ // input event missing on ie 8, fails to fire on backspace and delete keys in ie 9
+ if (ie <= 8 || (ie == 9 && (kc == 8 || kc == 46))) {
+ this.bubble("oninput", inEvent);
+ }
+ },
+ iekeydown: function(inSender, inEvent) {
+ var wp = enyo.platform.windowsPhone, kc = inEvent.keyCode, dt = inEvent.dispatchTarget;
+ // onchange event fails to fire on enter key for Windows Phone 8, so we force blur
+ if (wp <= 8 && kc == 13 && this.tag == "input" && dt.hasNode()) {
+ dt.node.blur();
+ }
+ },
+ clear: function() {
+ this.setValue("");
+ },
+ focus: function() {
+ if (this.hasNode()) {
+ this.node.focus();
+ }
+ },
+ //* Returns true if the Input is focused.
+ hasFocus: function() {
+ if (this.hasNode()) {
+ return document.activeElement === this.node;
+ }
+ },
+ // note: we disallow dragging of an input to allow text selection on all platforms
+ dragstart: function() {
+ return this.hasFocus();
+ },
+ focused: function() {
+ if (this.selectOnFocus) {
+ enyo.asyncMethod(this, "selectContents");
+ }
+ },
+ selectContents: function() {
+ var n = this.hasNode();
+
+ if (n && n.setSelectionRange) {
+ n.setSelectionRange(0, n.value.length);
+ } else if (n && n.createTextRange) {
+ var r = n.createTextRange();
+ r.expand("textedit");
+ r.select();
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiPopupjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/Popup.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/Popup.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/Popup.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,303 @@
</span><ins>+/**
+ _enyo.Popup_ is a control used to display certain content on top of other
+ content.
+
+ Popups are initially hidden on creation; they can be shown by calling the
+ _show_ method and re-hidden by calling _hide_. Popups may be centered using
+ the _centered_ property; if not centered, they should be given a specific
+ position.
+
+ A popup may be optionally floated above all application content by setting
+ its _floating_ property to _true_. This has the advantage of guaranteeing
+ that the popup will be displayed on top of other content. This usage is
+ appropriate when the popup does not need to scroll along with other content.
+
+ For more information, see the documentation on
+ [Popups](https://github.com/enyojs/enyo/wiki/Popups) in the Enyo Developer
+ Guide.
+ */
+enyo.kind({
+ name: "enyo.Popup",
+ classes: "enyo-popup enyo-no-touch-action",
+ published: {
+ //* Set to true to prevent controls outside the popup from receiving
+ //* events while the popup is showing
+ modal: false,
+ //* By default, the popup will hide when the user taps outside it or
+ //* presses ESC. Set to false to prevent this behavior.
+ autoDismiss: true,
+ //* Set to true to render the popup in a floating layer outside of other
+ //* controls. This can be used to guarantee that the popup will be
+ //* shown on top of other controls.
+ floating: false,
+ //* Set to true to automatically center the popup in the middle of the viewport
+ centered: false
+ },
+ //* @protected
+ showing: false,
+ handlers: {
+ ondown: "down",
+ onkeydown: "keydown",
+ ondragstart: "dragstart",
+ onfocus: "focus",
+ onblur: "blur",
+ onRequestShow: "requestShow",
+ onRequestHide: "requestHide"
+ },
+ captureEvents: true,
+ //* @public
+ events: {
+ //* Fires after the popup is shown.
+ onShow: "",
+ //* Fires after the popup is hidden.
+ onHide: ""
+ },
+ //* @protected
+ tools: [
+ {kind: "Signals", onKeydown: "keydown"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ /*if (this.floating) {
+ this.setParent(enyo.floatingLayer);
+ }*/
+ this.canGenerate = !this.floating;
+ },
+ render: function() {
+ if (this.floating) {
+ if (!enyo.floatingLayer.hasNode()) {
+ enyo.floatingLayer.render();
+ }
+ this.parentNode = enyo.floatingLayer.hasNode();
+ }
+ this.inherited(arguments);
+ },
+ destroy: function() {
+ if (this.showing) {
+ this.release();
+ }
+ this.inherited(arguments);
+ },
+
+ reflow: function() {
+ this.updatePosition();
+ this.inherited(arguments);
+ },
+ calcViewportSize: function() {
+ if (window.innerWidth) {
+ return {
+ width: window.innerWidth,
+ height: window.innerHeight
+ };
+ } else {
+ var e = document.documentElement;
+ return {
+ width: e.offsetWidth,
+ height: e.offsetHeight
+ };
+ }
+ },
+ updatePosition: function() {
+ var d = this.calcViewportSize();
+ var b = this.getBounds();
+
+ if (this.targetPosition) {
+ // For brevity's sake...
+ var p = this.targetPosition;
+
+ // Test and optionally adjust our target bounds (only first is commented, because logic is effectively identical for all scenarios)
+ if (typeof p.left === 'number') {
+ // If popup will be outside window bounds, switch anchor
+ if (p.left + b.width > d.width) {
+ if (p.left - b.width >= 0) {
+ // Switching to right corner will fit in window
+ p.right = d.width - p.left;
+ } else {
+ // Neither corner will work; stick at side of window
+ p.right = 0;
+ }
+ p.left = null;
+ } else {
+ p.right = null;
+ }
+ } else if (typeof p.right === 'number') {
+ if (p.right + b.width > d.width) {
+ if (p.right - b.width >= 0) {
+ p.left = d.width - p.right;
+ } else {
+ p.left = 0;
+ }
+ p.right = null;
+ } else {
+ p.left = null;
+ }
+ }
+
+ if (typeof p.top === 'number') {
+ if (p.top + b.height > d.height) {
+ if (p.top - b.height >= 0) {
+ p.bottom = d.height - p.top;
+ } else {
+ p.bottom = 0;
+ }
+ p.top = null;
+ } else {
+ p.bottom = null;
+ }
+ } else if (typeof p.bottom === 'number') {
+ if (p.bottom + b.height > d.height) {
+ if (p.bottom - b.height >= 0) {
+ p.top = d.height - p.bottom;
+ } else {
+ p.top = 0;
+ }
+ p.bottom = null;
+ } else {
+ p.top = null;
+ }
+ }
+
+ // 'initial' values are necessary to override positioning rules in the CSS
+ this.addStyles('left: ' + (p.left !== null ? p.left + 'px' : 'initial') + '; right: ' + (p.right !== null ? p.right + 'px' : 'initial') + '; top: ' + (p.top !== null ? p.top + 'px' : 'initial') + '; bottom: ' + (p.bottom !== null ? p.bottom + 'px' : 'initial') + ';');
+ } else if (this.centered) {
+ this.addStyles( "top: " + Math.max( ( ( d.height - b.height ) / 2 ), 0 ) + "px; left: " + Math.max( ( ( d.width - b.width ) / 2 ), 0 ) + "px;" );
+ }
+ },
+ showingChanged: function() {
+ // auto render when shown.
+ if (this.floating && this.showing && !this.hasNode()) {
+ this.render();
+ }
+ // hide while sizing, and move to top corner for accurate sizing
+ if (this.centered || this.targetPosition) {
+ this.applyStyle("visibility", "hidden");
+ this.addStyles("top: 0px; left: 0px; right: initial; bottom: initial;");
+ }
+ this.inherited(arguments);
+ if (this.showing) {
+ this.resized();
+ if (this.captureEvents) {
+ this.capture();
+ }
+ } else {
+ if (this.captureEvents) {
+ this.release();
+ }
+ }
+ // show after sizing
+ if (this.centered || this.targetPosition) {
+ this.applyStyle("visibility", null);
+ }
+ // events desired due to programmatic show/hide
+ if (this.hasNode()) {
+ this[this.showing ? "doShow" : "doHide"]();
+ }
+ },
+ capture: function() {
+ enyo.dispatcher.capture(this, !this.modal);
+ },
+ release: function() {
+ enyo.dispatcher.release();
+ },
+ down: function(inSender, inEvent) {
+ //record the down event to verify in tap
+ this.downEvent = inEvent;
+
+ // prevent focus from shifting outside the popup when modal.
+ if (this.modal && !inEvent.dispatchTarget.isDescendantOf(this)) {
+ inEvent.preventDefault();
+ }
+ },
+ tap: function(inSender, inEvent) {
+ // dismiss on tap if property is set and click started & ended outside the popup
+ if (this.autoDismiss && (!inEvent.dispatchTarget.isDescendantOf(this)) && this.downEvent &&
+ (!this.downEvent.dispatchTarget.isDescendantOf(this))) {
+ this.downEvent = null;
+ this.hide();
+ return true;
+ }
+ },
+ // if a drag event occurs outside a popup, hide
+ dragstart: function(inSender, inEvent) {
+ var inScope = (inEvent.dispatchTarget === this || inEvent.dispatchTarget.isDescendantOf(this));
+ if (inSender.autoDismiss && !inScope) {
+ inSender.setShowing(false);
+ }
+ return true;
+ },
+ keydown: function(inSender, inEvent) {
+ if (this.showing && this.autoDismiss && inEvent.keyCode == 27 /* escape */) {
+ this.hide();
+ }
+ },
+ // If something inside the popup blurred, keep track of it.
+ blur: function(inSender, inEvent) {
+ if (inEvent.dispatchTarget.isDescendantOf(this)) {
+ this.lastFocus = inEvent.originator;
+ }
+ },
+ // When something outside the popup focuses (e.g., due to tab key), focus our last focused control.
+ focus: function(inSender, inEvent) {
+ var dt = inEvent.dispatchTarget;
+ if (this.modal && !dt.isDescendantOf(this)) {
+ if (dt.hasNode()) {
+ dt.node.blur();
+ }
+ var n = (this.lastFocus && this.lastFocus.hasNode()) || this.hasNode();
+ if (n) {
+ n.focus();
+ }
+ }
+ },
+ requestShow: function(inSender, inEvent) {
+ this.show();
+ return true;
+ },
+ requestHide: function(inSender, inEvent) {
+ this.hide();
+ return true;
+ },
+
+ //* @public
+ /**
+ Open at the location of a mouse event (_inEvent_). The popup's
+ position is automatically constrained so that it does not
+ display outside the viewport, and defaults to anchoring the top
+ left corner of the popup to the mouse event.
+
+ _inOffset_ is an optional object which may contain left and top
+ properties to specify an offset relative to the location the
+ popup would otherwise be positioned.
+ */
+ showAtEvent: function(inEvent, inOffset) {
+ // Calculate our ideal target based on the event position and offset
+ var p = {
+ left: inEvent.centerX || inEvent.clientX || inEvent.pageX,
+ top: inEvent.centerY || inEvent.clientY || inEvent.pageY
+ };
+ if (inOffset) {
+ p.left += inOffset.left || 0;
+ p.top += inOffset.top || 0;
+ }
+
+ this.showAtPosition(p);
+ },
+
+ /**
+ Open the popup at a specific position. The final location
+ of the popup will be automatically constrained so that it does not
+ display outside the viewport.
+
+ _inPosition_ is an object which may contain left, top, bottom,
+ and right properties to specify where the popup will be anchored.
+ If both left and right are included, the popup will preference left
+ (same for top vs. bottom).
+ */
+ showAtPosition: function(inPosition) {
+ // Save our target position for later processing
+ this.targetPosition = inPosition;
+
+ // Show the dialog
+ this.show();
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiRepeaterjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/Repeater.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/Repeater.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/Repeater.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,108 @@
</span><ins>+/**
+ _enyo.Repeater_ is a simple control for making lists of items.
+
+ The components of a repeater are copied for each item created, and are
+ wrapped in a control that keeps the state of the item index.
+
+ Example:
+
+ {kind: "Repeater", count: 2, onSetupItem: "setImageSource", components: [
+ {kind: "Image"}
+ ]}
+
+ setImageSource: function(inSender, inEvent) {
+ var index = inEvent.index;
+ var item = inEvent.item;
+ item.$.image.setSrc(this.imageSources[index]);
+ return true;
+ }
+
+ Be sure to return _true_ from your _onSetupItem_ handler to avoid having
+ other event handlers further up the tree try to modify your item control.
+
+ For more information, see the documentation on
+ [Lists](https://github.com/enyojs/enyo/wiki/Lists) in the Enyo Developer
+ Guide.
+*/
+enyo.kind({
+ name: "enyo.Repeater",
+ published: {
+ //* Number of items
+ count: 0
+ },
+ events: {
+ /**
+ Fires when each item is created.
+
+ _inEvent.index_ contains the item's index.
+
+ _inEvent.item_ contains the item control, for decoration.
+ */
+ onSetupItem: ""
+ },
+ create: function() {
+ this.inherited(arguments);
+ this.countChanged();
+ },
+ //* @protected
+ initComponents: function() {
+ this.itemComponents = this.components || this.kindComponents;
+ this.components = this.kindComponents = null;
+ this.inherited(arguments);
+ },
+ setCount: function(inCount) {
+ this.setPropertyValue("count", inCount, "countChanged");
+ },
+ countChanged: function() {
+ this.build();
+ },
+ itemAtIndex: function(inIndex) {
+ return this.controlAtIndex(inIndex);
+ },
+ //* @public
+ /** Renders the collection of items. This will delete any existing items and
+ recreate the repeater if called after the repeater has been rendered.
+ This is called automatically if _setCount_ is called, even if the count
+ remains the same.
+ */
+ build: function() {
+ this.destroyClientControls();
+ for (var i=0, c; i<this.count; i++) {
+ c = this.createComponent({kind: "enyo.OwnerProxy", index: i});
+ // do this as a second step so 'c' is the owner of the created components
+ c.createComponents(this.itemComponents);
+ // invoke user's setup code
+ this.doSetupItem({index: i, item: c});
+ }
+ this.render();
+ },
+ /**
+ Renders a specific item in the collection. This does not destroy the
+ item, but just calls the _onSetupItem_ event handler again for it, so
+ any state stored in the item is preserved.
+ */
+ renderRow: function(inIndex) {
+ var c = this.itemAtIndex(inIndex);
+ this.doSetupItem({index: inIndex, item: c});
+ }
+});
+
+// Sometimes client controls are intermediated with null-controls.
+// These overrides reroute events from such controls to the nominal delegate,
+// as would happen in the absence of intermediation.
+enyo.kind({
+ name: "enyo.OwnerProxy",
+ tag: null,
+ decorateEvent: function(inEventName, inEvent, inSender) {
+ if (inEvent) {
+ inEvent.index = this.index;
+ }
+ this.inherited(arguments);
+ },
+ delegateEvent: function(inDelegate, inName, inEventName, inEvent, inSender) {
+ if (inDelegate == this) {
+ inDelegate = this.owner.owner;
+ }
+ return this.inherited(arguments, [inDelegate, inName, inEventName, inEvent, inSender]);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiRichTextjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/RichText.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/RichText.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/RichText.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,138 @@
</span><ins>+/**
+ _enyo.RichText_ is a multi-line text input that supports rich formatting,
+ such as bold, italics, and underlining.
+
+ The content displayed in a RichText may be accessed at runtime via the
+ `getValue` and `setValue` methods.
+
+ For more information, see the documentation on
+ [Text Fields](https://github.com/enyojs/enyo/wiki/Text-Fields) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.RichText",
+ classes: "enyo-richtext enyo-selectable",
+ published: {
+ /**
+ _allowHtml_ is enabled by default in RichText to take advantage of
+ all the rich editing properties. However, this allows for **ANY**
+ HTML to be inserted into the RichText, including _iframe_ and
+ _script_ tags, which can be a secuity concern in some situations.
+ If set to false, inserted HTML will be escaped.
+ */
+ allowHtml: true,
+ //* If true, the RichText will not accept input or generate events
+ disabled: false,
+ //* Value of the text field
+ value: ""
+ },
+ //* Set to true to focus this control when it is rendered.
+ defaultFocus: false,
+ //* @protected
+ statics: {
+ osInfo: [
+ {os: "android", version: 3},
+ {os: "ios", version: 5}
+ ],
+ //* Returns true if the platform has contenteditable attribute.
+ hasContentEditable: function() {
+ for (var i=0, t, m; t=enyo.RichText.osInfo[i]; i++) {
+ if (enyo.platform[t.os] < t.version) {
+ return false;
+ }
+ }
+ return true;
+ }
+ },
+ kind: enyo.Input,
+ attributes: {
+ contenteditable: true
+ },
+ handlers: {
+ onfocus: "focusHandler",
+ onblur: "blurHandler"
+ },
+ // create RichText as a div if platform has contenteditable attribute, otherwise create it as a textarea
+ create: function() {
+ this.setTag(enyo.RichText.hasContentEditable()?"div":"textarea");
+ this.inherited(arguments);
+ },
+ // simulate onchange event that inputs expose
+ focusHandler: function() {
+ this._value = this.getValue();
+ },
+ blurHandler: function() {
+ if (this._value !== this.getValue()) {
+ this.bubble("onchange");
+ }
+ },
+ valueChanged: function() {
+ if (this.hasFocus()) {
+ this.selectAll();
+ this.insertAtCursor(this.value);
+ } else {
+ this.setPropertyValue("content", this.value, "contentChanged");
+ }
+ },
+ //* @public
+ //* Gets value of the RichText.
+ getValue: function() {
+ if (this.hasNode()) {
+ return this.node.innerHTML;
+ }
+ },
+ //* Returns true if the RichText is focused.
+ hasFocus: function() {
+ if (this.hasNode()) {
+ return document.activeElement === this.node;
+ }
+ },
+ /**
+ Returns the selection object.
+ */
+ getSelection: function() {
+ if (this.hasFocus()) {
+ return window.getSelection();
+ }
+ },
+ //* Removes the selection object.
+ removeSelection: function(inStart) {
+ var s = this.getSelection();
+ if (s) {
+ s[inStart ? "collapseToStart" : "collapseToEnd"]();
+ }
+ },
+ //* Modifies the selection object.
+ modifySelection: function(inType, inDirection, inAmount) {
+ var s = this.getSelection();
+ if (s) {
+ s.modify(inType || "move", inDirection, inAmount);
+ }
+ },
+ //* Moves the cursor according to the Editing API.
+ moveCursor: function(inDirection, inAmount) {
+ this.modifySelection("move", inDirection, inAmount);
+ },
+ //* Moves the cursor to end of text field.
+ moveCursorToEnd: function() {
+ this.moveCursor("forward", "documentboundary");
+ },
+ //* Moves the cursor to start of text field.
+ moveCursorToStart: function() {
+ this.moveCursor("backward", "documentboundary");
+ },
+ //* Selects all content in text field.
+ selectAll: function() {
+ if (this.hasFocus()) {
+ document.execCommand("selectAll");
+ }
+ },
+ //* Inserts HTML at the cursor position. HTML is escaped unless the
+ //* _allowHTML_ property is true.
+ insertAtCursor: function(inValue) {
+ if (this.hasFocus()) {
+ var v = this.allowHtml ? inValue : enyo.Control.escapeHtml(inValue).replace(/\n/g, "<br/>");
+ document.execCommand("insertHTML", false, v);
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiSelectjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/Select.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/Select.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/Select.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,116 @@
</span><ins>+/**
+ _enyo.Select_ implements an HTML selection widget, using
+ [enyo.Option](#enyo.Option) kinds by default.
+
+ Example:
+
+ {kind: "Select", onchange: "selectChanged", components: [
+ {content: "Descending", value: "d"},
+ {content: "Ascending", value: "a"}
+ ]}
+
+ selectChanged: function(inSender, inEvent) {
+ var s = inSender.getValue();
+ if (s == "d") {
+ this.sortListDescending();
+ } else {
+ this.sortListAscending();
+ }
+ }
+
+ Note: This uses the `<select>` tag, which isn't implemented
+ for native webOS applications, although it does work in the
+ webOS Web browser.
+*/
+
+enyo.kind({
+ name: "enyo.Select",
+ published: {
+ //* Index of the selected option in the list
+ selected: 0
+ },
+ //* @protected
+ handlers: {
+ onchange: "change"
+ },
+ tag: "select",
+ defaultKind: "enyo.Option",
+ rendered: function() {
+ this.inherited(arguments);
+ //Trick to force IE8 onchange event bubble
+ if(enyo.platform.ie == 8){
+ this.setAttribute("onchange", enyo.bubbler);
+ }
+ this.selectedChanged();
+ },
+ getSelected: function() {
+ return Number(this.getNodeProperty("selectedIndex", this.selected));
+ },
+ setSelected: function(inIndex) {
+ // default property mechanism can't track changed correctly for virtual properties
+ this.setPropertyValue("selected", Number(inIndex), "selectedChanged");
+ },
+ selectedChanged: function() {
+ this.setNodeProperty("selectedIndex", this.selected);
+ },
+ change: function() {
+ this.selected = this.getSelected();
+ },
+ render: function() {
+ // work around IE bug with innerHTML setting of <select>, rerender parent instead
+ // http://support.microsoft.com/default.aspx?scid=kb;en-us;276228
+ if (enyo.platform.ie) {
+ this.parent.render();
+ } else {
+ this.inherited(arguments);
+ }
+ },
+ //* @public
+ //* Returns the value of the selected option.
+ getValue: function() {
+ if (this.hasNode()) {
+ return this.node.value;
+ }
+ }
+});
+
+/**
+ _enyo.Option_ implements the options in an HTML select widget.
+*/
+enyo.kind({
+ name: "enyo.Option",
+ published: {
+ //* Value of the option
+ value: ""
+ },
+ //* @protected
+ tag: "option",
+ create: function() {
+ this.inherited(arguments);
+ this.valueChanged();
+ },
+ valueChanged: function() {
+ this.setAttribute("value", this.value);
+ }
+});
+
+/**
+ _enyo.OptionGroup_ allows for the grouping of options in a select widget,
+ and for the disabling of blocks of options.
+*/
+enyo.kind({
+ name: "enyo.OptionGroup",
+ published: {
+ label: ""
+ },
+ //* @protected
+ tag: "optgroup",
+ defaultKind: "enyo.Option",
+ create: function() {
+ this.inherited(arguments);
+ this.labelChanged();
+ },
+ labelChanged: function() {
+ this.setAttribute("label", this.label);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiSelectionjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/Selection.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/Selection.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/Selection.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,171 @@
</span><ins>+/**
+ _enyo.Selection_ is used to manage row selection state for lists. It
+ provides selection state management for both single-select and multi-select
+ lists.
+
+ // The following is an excerpt from enyo.FlyweightRepeater.
+ enyo.kind({
+ name: "enyo.FlyweightRepeater",
+ ...
+ components: [
+ {kind: "Selection", onSelect: "selectDeselect", onDeselect: "selectDeselect"},
+ ...
+ ],
+ tap: function(inSender, inEvent) {
+ ...
+ // mark the tapped row as selected
+ this.$.selection.select(inEvent.index);
+ ...
+ },
+ selectDeselect: function(inSender, inEvent) {
+ // this is where a row selection highlight might be applied
+ this.renderRow(inEvent.key);
+ }
+ ...
+ })
+*/
+enyo.kind({
+ name: "enyo.Selection",
+ kind: enyo.Component,
+ published: {
+ //* If true, multiple selections are allowed
+ multi: false
+ },
+ events: {
+ /**
+ Fires when an item is selected.
+
+ {kind: "Selection", onSelect: "selectRow"...
+ ...
+ selectRow: function(inSender, inEvent) {
+ ...
+
+ _inEvent.key_ is whatever key was used to register the selection
+ (usually a row index).
+
+ _inEvent.data_ references data registered with this key by the code
+ that made the original selection.
+ */
+ onSelect: "",
+ /**
+ Fires when an item is deselected.
+
+ {kind: "Selection", onSelect: "deselectRow"...
+ ...
+ deselectRow: function(inSender, inEvent)
+ ...
+
+ _inEvent.key_ is whatever key was used to request the deselection
+ (usually a row index).
+
+ _inEvent.data_ references data registered with this key by the code
+ that made the selection.
+ */
+ onDeselect: "",
+ //* Fires when selection changes (but not when selection is cleared).
+ onChange: ""
+ },
+ //* @protected
+ create: function() {
+ this.clear();
+ this.inherited(arguments);
+ },
+ multiChanged: function() {
+ if (!this.multi) {
+ this.clear();
+ }
+ this.doChange();
+ },
+ highlander: function(inKey) {
+ if (!this.multi) {
+ this.deselect(this.lastSelected);
+ }
+ },
+ //* @public
+ //* Removes all selections.
+ clear: function() {
+ this.selected = {};
+ },
+ //* Returns true if the _inKey_ row is selected.
+ isSelected: function(inKey) {
+ return this.selected[inKey];
+ },
+ /**
+ Manually sets a row's state to selected or unselected.
+
+ _inData_ is an optional data object to store in the selection for
+ that key that will be sent with the _onSelect_ or _onDeselect_ events.
+ If not used, the data will be set to 'true'.
+ */
+ setByKey: function(inKey, inSelected, inData) {
+ if (inSelected) {
+ this.selected[inKey] = (inData || true);
+ this.lastSelected = inKey;
+ this.doSelect({key: inKey, data: this.selected[inKey]});
+ } else {
+ var was = this.isSelected(inKey);
+ delete this.selected[inKey];
+ this.doDeselect({key: inKey, data: was});
+ }
+ this.doChange();
+ },
+ //* Deselects a row.
+ deselect: function(inKey) {
+ if (this.isSelected(inKey)) {
+ this.setByKey(inKey, false);
+ }
+ },
+ /**
+ Selects a row. If the _multi_ property is set to false, _select_ will
+ also deselect the previous selection.
+
+ _inData_ is an optional data object to store in the selection for
+ that key that will be sent with the _onSelect_ or _onDeselect_ events.
+ If not used, the data will be set to 'true'.
+ */
+ select: function(inKey, inData) {
+ if (this.multi) {
+ this.setByKey(inKey, !this.isSelected(inKey), inData);
+ } else if (!this.isSelected(inKey)) {
+ this.highlander();
+ this.setByKey(inKey, true, inData);
+ }
+ },
+ /**
+ Toggles selection state for a row. If the _multi_ property is set to
+ false, toggling a selection on will deselect the previous selection.
+
+ _inData_ is an optional data object to store in the selection for
+ that key that will be sent with the _onSelect_ or _onDeselect_ events.
+ If not used, the data will be set to 'true'.
+ */
+ toggle: function(inKey, inData) {
+ if (!this.multi && this.lastSelected != inKey) {
+ this.deselect(this.lastSelected);
+ }
+ this.setByKey(inKey, !this.isSelected(inKey), inData);
+ },
+ /**
+ Returns the selection as a hash in which each selected item has a value;
+ unselected items are undefined.
+ */
+ getSelected: function() {
+ return this.selected;
+ },
+ /**
+ Remove a row that's included in the selection set. If this row is
+ selected, it will be unselected. Any rows above this row will
+ have their keys value reduced by one.
+ */
+ remove: function(inKey) {
+ var newSelected = {};
+ for (var row in this.selected) {
+ if (row < inKey) {
+ newSelected[row] = this.selected[row];
+ } else if (row > inKey) {
+ newSelected[row - 1] = this.selected[row];
+ }
+ }
+ this.selected = newSelected;
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiTextAreajs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/TextArea.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/TextArea.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/TextArea.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+/**
+ _enyo.TextArea_ implements an HTML <textarea> element with
+ cross-platform support for change events.
+
+ For more information, see the documentation on
+ [Text Fields](https://github.com/enyojs/enyo/wiki/Text-Fields) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.TextArea",
+ kind: enyo.Input,
+ //* @protected
+ tag: "textarea",
+ classes: "enyo-textarea",
+ // textarea does use value attribute; needs to be kicked when rendered.
+ rendered: function() {
+ this.inherited(arguments);
+ this.valueChanged();
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiToolDecoratorjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/ToolDecorator.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/ToolDecorator.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/ToolDecorator.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+/**
+ _enyo.ToolDecorator_ lines up components in a row, centered vertically.
+*/
+enyo.kind({
+ name: "enyo.ToolDecorator",
+ //* @protected
+ kind: enyo.GroupItem,
+ classes: "enyo-tool-decorator"
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuipackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+enyo.depends(
+ "ui.css",
+ "Animator.js",
+ "BaseLayout.js",
+ "Image.js",
+ "Input.js",
+ "RichText.js",
+ "TextArea.js",
+ "Select.js",
+ "Group.js",
+ "GroupItem.js",
+ "ToolDecorator.js",
+ "Button.js",
+ "Checkbox.js",
+ "Repeater.js",
+ "DragAvatar.js",
+ "FloatingLayer.js",
+ "Popup.js",
+ "Selection.js"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyosourceuiuicss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/source/ui/ui.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/source/ui/ui.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/source/ui/ui.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+.enyo-inline, .enyo-tool-decorator {
+ display: inline-block;
+}
+
+.enyo-children-inline > *, .enyo-tool-decorator > * {
+ display: inline-block;
+}
+
+.enyo-children-middle > *, .enyo-tool-decorator > * {
+ vertical-align: middle;
+}
+
+.enyo-positioned {
+ position: relative;
+}
+
+.enyo-fill {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+.enyo-popup {
+ position: absolute;
+ z-index: 10;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsREADMEmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/README.md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/README.md (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/README.md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+# Enyo Minifier
+
+The enyo minifier uses Node.js, [UglifyJS](http://github.com/mishoo/uglifyjs) and the enyo dependency loader to compress any enyo package into a minimized form.
+
+## Invocation
+For convenience, there are both Windows and Unix versions of the script that invokes the node tool.
+They follow the same invocation:
+
+ path/to/enyo/tools/minify/minify.sh package.js -output /relative/path/to/build/dir/buildfilename
+
+An example for lib/onyx, a UI widget set, run from `lib/onyx/minify/minify.sh`, building to `lib/onyx/build`
+
+ ../../../enyo/tools/minify/minify.sh -output ../build/onyx package.js
+
+The last parameter in the output path, if not ending in a `/`, will be used as the name of the output build files.
+The `package.js` file must be in the same directory as the invocation.
+
+For convenience, packages should include a `minify` folder with both a Windows batch and Unix shell script that runs the minifier.
+
+## Running tests
+1. You first need to install an http server handling php (MANP or WAMP, ...)
+2. Configure your http server to serve the files of the enyo project
+3. Point your browser to enyo/tools/... to run the various testcases
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsdeployjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/deploy.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/deploy.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/deploy.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,230 @@
</span><ins>+#!/usr/bin/env node
+
+/**
+# deploy.js - portable deployment script
+
+This portable Node.js script minifies both your application, its
+libraries & the Enyo framework it is using. The resulting application
+is suitable for production usage, either hostet on a web-server or
+embedded into a PhoneGap container.
+
+The script is intended to be run from the application's root directory
+(This is unlike previous deprecated incarnations of the scripts
+`deploy.sh` and `deploy.bat` that shipped within the `bootplate`
+application), where it expects to find a file called `package.js`
+(unless the user specifies an alternate location using the `-p` flag).
+
+This script comes along with Enyo. It automatically uses & embeds the
+Enyo version it is shipped with, unless the user specifies another
+Enyo version using the `-e enyo_dir` flag.
+
+When you application has library dependencies (for example
+`lib/mylib`), this script uses the `lib/mylib/manifest.json` (if
+present) or the old-fashioned deployment scripts `lib/mylib/deploy.sh`
+(on Linux & Mac OSX) or `lib/mylib/deploy.bat` (on Windows).
+If neither exist, then the entire library is copied (except for .git dir).
+
+This script also expects to find the following files & folders in the
+application root directory. Each of them is copied verbatim in the
+output production/deployment folder (the one optionally given using
+the `-o` flag).
+
+* `index.html`, the application startup page
+* `icon.png`, the application icon
+* `assets/`holds the static application assets, such as images,
+ videos... etc.
+
+ */
+
+// Load dependencies
+
+var nopt = require("nopt"),
+ path = require('path'),
+ fs = require('fs'),
+ util = require('util'),
+ shell = require('shelljs');
+
+var stat, ppwd, lib, script, scripts = {};
+
+// Send message to parent node process, if any
+process.on('uncaughtException', function (err) {
+ var errMsg = err.toString() + err.stack;
+ console.error(errMsg);
+ if (process.send) {
+ // only available if parent process is node
+ process.send({error: errMsg});
+ }
+ process.exit(1);
+});
+// receive error messages from child node processes
+process.on('message', function(msg) {
+ console.dir(basename, msg);
+ if (msg.error && msg.error.stack) {
+ console.error(basename, msg.error.stack);
+ }
+ if (process.send) {
+ process.send(msg);
+ }
+});
+
+// Parse arguments
+
+var node = process.argv[0],
+ deploy = process.argv[1],
+ sourceDir = process.cwd(),
+ packageJs = path.resolve(sourceDir, "package.js"),
+ enyoDir = path.resolve(__dirname, '..'),
+ buildDir = path.resolve(sourceDir, "build"),
+ name = path.basename(sourceDir),
+ outDir = path.resolve(sourceDir, 'deploy', name),
+ less = true, // LESS compilation, turned on by default
+ verbose = false;
+
+function printUsage() {
+ // format generated using node-optimist...
+ console.log('\n' +
+ 'Usage: ' + node + ' ' + deploy + ' [-c][-e enyo_dir][-b build_dir][-o out_dir][-p package_js][-s source_dir]\n' +
+ '\n' +
+ 'Options:\n' +
+ ' -v verbose operation [boolean] [default: ' + verbose + ']\n' +
+ ' -b alternate build directory [default: "' + buildDir + '"]\n' +
+ ' -c do not run the LESS compiler [boolean] [default: ' + less + ']\n' +
+ ' -e location of the enyo framework [default: "' + enyoDir + '"]\n' +
+ ' -o alternate output directory [default: "' + outDir + '"]\n' +
+ ' -p location of the main package.js file [default: "' + packageJs + '"]\n' +
+ ' -s source code root directory [default: "' + sourceDir + '"]\n' +
+ '\n');
+}
+
+var opt = nopt(/*knownOpts*/ {
+ "build": path,
+ "less": Boolean,
+ "enyo": path,
+ "out": path,
+ "packagejs": path,
+ "source": path,
+ "verbose": Boolean,
+ "help": Boolean
+}, /*shortHands*/ {
+ "b": "--build",
+ "c": "--no-less",
+ "e": "--enyo",
+ "o": "--out",
+ "p": "--packagejs",
+ "s": "--source",
+ "v": "--verbose",
+ "h": "--help",
+ "?": "--help"
+}, process.argv /*args*/, 2 /*slice*/);
+
+if (opt.help) {
+ printUsage();
+ process.exit(1);
+}
+
+// nopt has not default values system
+buildDir = opt.build || buildDir;
+enyoDir = opt.enyo || enyoDir;
+outDir = opt.out || outDir;
+packageJs = opt.packagejs ||
+ (opt.source ? path.join(opt.source, 'package.js') : undefined) ||
+ packageJs;
+sourceDir = opt.source ||
+ (opt.packagejs ? path.dirname(opt.packagejs) : undefined) ||
+ sourceDir;
+less = (opt.less !== false) && less;
+verbose = opt.verbose;
+
+var minifier = path.resolve(enyoDir, 'tools', 'minifier', 'minify.js');
+if (verbose) console.log("Using: build_dir=" + buildDir);
+if (verbose) console.log("Using: enyo_dir=" + enyoDir);
+if (verbose) console.log("Using: out_dir=" + outDir);
+if (verbose) console.log("Using: packagejs=" + packageJs);
+if (verbose) console.log("Using: source_dir=" + sourceDir);
+if (verbose) console.log("Using: less=" + less);
+
+// utils
+
+function run(args) {
+ var command = '"' + args.join('" "') + '"';
+ var report;
+ if (verbose) console.log("Running: '", command, "' from '", process.cwd(), "'");
+ report = shell.exec(command, { silent: true });
+ if (report.code !== 0) {
+ throw new Error("Fail: '" + command + "'\n" + report.output);
+ }
+}
+
+// Prepare target directory
+
+shell.rm('-rf', path.resolve(outDir));
+shell.rm('-rf', path.resolve(outDir));
+shell.mkdir('-p', path.join(outDir));
+
+// Build / Minify
+
+console.log("Minify-ing Enyo...");
+process.chdir(path.resolve(enyoDir, 'minify'));
+run([node, minifier,
+ '-no-alias',
+ '-enyo', enyoDir,
+ // XXX generates $buildDir/enyo.(js|css)' so this is
+ // XXX rather an 'output_prefix' than an 'out_dir'...
+ '-output', path.join(buildDir, 'enyo'),
+ 'package.js']);
+
+console.log("Minify-ing the application...");
+process.chdir(path.dirname(packageJs));
+run([node, minifier,
+ '-enyo', enyoDir,
+ '-output', path.join(buildDir, 'app'),
+ (less ? '-less' : '-no-less'),
+ 'package.js']);
+process.chdir(sourceDir);
+
+// Deploy / Copy
+
+shell.mkdir('-p', path.join(outDir, 'lib'));
+shell.cp(path.join(sourceDir, 'index.html'), path.join(sourceDir, 'icon.png'), outDir);
+shell.cp('-r', buildDir, outDir);
+
+var assetsSrcDir = path.join(sourceDir, 'assets');
+if(shell.test('-d', assetsSrcDir)) {
+ shell.cp('-r', assetsSrcDir, outDir);
+}
+
+var libSrcDir = path.join(sourceDir, 'lib');
+if(shell.test('-d', libSrcDir)) {
+ shell.ls(libSrcDir).forEach(deployLib);
+}
+
+function deployLib(lib) {
+ var libOutdir = path.join(outDir, 'lib', lib);
+ // load & execute sub-'deploy.js'
+ try {
+ script = path.join(sourceDir, 'lib', lib, 'deploy.js');
+ stat = fs.statSync(script);
+ if (!stat.isFile())
+ throw new Error("*** Not a file: '" + script + "'");
+ scripts[lib] = require(script);
+ scripts[lib].deploy(libOutdir);
+ } catch(e) {
+ // backward compatibility: run deploy.sh or deploy.bat
+ try {
+ script = path.join(sourceDir, 'lib', lib, 'deploy.' + (process.platform === 'win32' ? 'bat' : 'sh'));
+ stat = fs.statSync(script);
+ if (!stat.isFile())
+ throw new Error("*** Not a file: '" + script + "'");
+ run([script, libOutdir]);
+ } catch(e2) {
+ // no deploy.(js|bat|sh): copy everything (then remove ".git", if any)
+ shell.cp('-r', path.join(sourceDir, 'lib', lib), path.join(outDir, 'lib'));
+ shell.rm('-rf', path.join(outDir, 'lib', lib, '.git'));
+ }
+ }
+}
+
+console.log("Success: the deployable application is available in: ", outDir);
+process.exit(0);
+
+
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/deploy.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolslesscbat"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/lessc.bat (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/lessc.bat (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/lessc.bat 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+REM don't watch the sausage being made
+@ECHO OFF
+
+REM the folder this script is in (*/enyo/tools)
+SET TOOLS=%~DP0
+
+REM enyo location
+SET ENYO=%TOOLS%\..
+
+REM lessc script location
+SET LESSC=%TOOLS%\minifier\lessc.js
+
+REM node location
+SET NODE=node.exe
+
+REM use node to invoke lessc with a known path to enyo and imported parameters
+%NODE% "%LESSC%" -enyo "%ENYO%" %*
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolslesscsh"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/lessc.sh (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/lessc.sh (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/lessc.sh 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+#!/bin/bash
+
+# the folder this script is in (*/enyo/tools)
+TOOLS="$(cd `dirname $0`; pwd)"
+# enyo location
+ENYO="$TOOLS/.."
+# lessc script location
+LESSC="$TOOLS/minifier/lessc.js"
+
+# check for node, but quietly
+if command -v node >/dev/null 2>&1; then
+ # use node to invoke minify with a known path to enyo and imported parameters
+ echo "enyo/tools/lessc.sh args: " $@
+ node "$LESSC" -enyo "$ENYO" $@
+else
+ echo "No node found in path"
+ exit 1
+fi
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/lessc.sh
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsminifierlesscjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/lessc.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/lessc.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/lessc.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,80 @@
</span><ins>+var
+ fs = require("fs"),
+ path = require("path"),
+ walker = require("walker"),
+ jsp = require("uglify-js").parser,
+ pro = require("uglify-js").uglify,
+ nopt = require("nopt"),
+ less = require("less")
+ ;
+
+// Shimming path.relative with 0.8.8's version if it doesn't exist
+if(!path.relative){
+ path.relative = require('./path-relative-shim').relative;
+}
+
+function printUsage() {
+ w("Enyo Less->CSS Compiler");
+ w("-enyo ENYOPATH:", "Path to enyo loader (enyo/enyo.js)");
+ w("-output PATH/NAME:", "name of output file, prepend folder paths to change output directory");
+ w("-h, -?, -help:", "Show this message");
+}
+
+function finish(loader) {
+ for (var i=0, sheet; (sheet=loader.sheets[i]); i++) {
+ if (sheet.slice(-5) == ".less") {
+ w(sheet);
+ var code = fs.readFileSync(sheet, "utf8");
+ var parser = new(less.Parser)({filename:sheet, paths:[path.dirname(sheet)]});
+ var cssFile = sheet.slice(0,sheet.length-5) + ".css";
+ parser.parse(code, function (err, tree) {
+ if (err) {
+ console.error(err);
+ } else {
+ var css =
+ "/* WARNING: This is a generated file for backward-compatibility. Most */\n" +
+ "/* usrs should instead modify LESS files. If you choose to edit this CSS */\n" +
+ "/* directly rather than LESS files, you should make sure less.xx.yy.min.js */\n" +
+ "/* is commented out in your debug.html, and run deploy.sh/bat using the */\n" +
+ "/* '-c' flag to disable LESS compilation. This will force the loader and */\n" +
+ "/* minifier to fall back to using CSS files in place of the same-name */\n" +
+ "/* LESS file. */\n" +
+ "\n" + tree.toCSS()
+ fs.writeFileSync(cssFile, css, "utf8");
+ }
+ });
+ }
+ }
+}
+
+w = console.log;
+
+var knownOpts = {
+ "enyo": String,
+ "output": String,
+ "help": Boolean
+};
+
+var shortHands = {
+ "enyo": ['--enyo'],
+ "output": ['--output'],
+ "h": ['--help'],
+ "?": ['--help'],
+ "help": ['--help']
+};
+
+opt = nopt(knownOpts, shortHands, process.argv, 2);
+opt.source = opt.argv.remain[0];
+//w(opt);
+//w("");
+
+w("");
+
+if (opt.help) {
+ printUsage();
+ process.exit();
+}
+
+walker.init(opt.enyo);
+walker.walk(opt.source, finish);
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifierminifyjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/minify.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/minify.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/minify.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,231 @@
</span><ins>+var
+ fs = require("fs"),
+ path = require("path"),
+ walker = require("walker"),
+ jsp = require("uglify-js").parser,
+ pro = require("uglify-js").uglify,
+ nopt = require("nopt"),
+ less = require("less")
+ ;
+
+var basename = path.basename(__filename),
+ w = console.log,
+ e = console.error;
+
+// Shimming path.relative with 0.8.8's version if it doesn't exist
+if(!path.relative){
+ path.relative = require('./path-relative-shim').relative;
+}
+
+function printUsage() {
+ w("Enyo 2.0 Minifier");
+ w("Flags:");
+ w("-no-less:", "Don't compile less; instad substitute css for less");
+ w("-no-alias:", "Don't use path macros");
+ w("-alias:", "Give paths a macroized alias");
+ w("-enyo ENYOPATH:", "Path to enyo loader (enyo/enyo.js)");
+ w("-output PATH/NAME:", "name of output file, prepend folder paths to change output directory");
+ w("-h, -?, -help:", "Show this message");
+}
+
+// properly split path based on platform
+function pathSplit(inPath) {
+ var sep = process.platform == "win32" ? "\\" : "/";
+ return inPath.split(sep);
+}
+
+buildPathBlock = function(loader) {
+ var p$ = [];
+ for (var i=0, p; (p=loader.packages[i]); i++) {
+ if (p.name.indexOf("-") == -1) {
+ p$.push(p.name + ': "' + p.folder + '"');
+ }
+ }
+ p = p$.join(', ');
+ return !p ? "" : "\n// minifier: path aliases\n\nenyo.path.addPaths({" + p + "});\n";
+};
+
+concatCss = function(loader, doneCB) {
+ w("");
+ var blob = "";
+ var addToBlob = function(sheet, code) {
+ // fix url paths
+ code = code.replace(/url\([^)]*\)/g, function(inMatch) {
+ // find the url path, ignore quotes in url string
+ var matches = /url\s*\(\s*(('([^']*)')|("([^"]*)")|([^'"]*))\s*\)/.exec(inMatch);
+ var urlPath = matches[3] || matches[5] || matches[6];
+ // skip data urls
+ if (/^data:/.test(urlPath)) {
+ return "url(" + urlPath + ")";
+ }
+ // skip an external link
+ if (/^http(:?s)?:/.test(urlPath)) {
+ return "url(" + urlPath + ")";
+ }
+ // get absolute path to referenced asset
+ var normalizedUrlPath = path.join(sheet, "..", urlPath);
+ // Make relative asset path to built css
+ var relPath = path.relative(path.dirname(opt.output || "build"), normalizedUrlPath);
+ if (process.platform == "win32") {
+ relPath = pathSplit(relPath).join("/");
+ }
+ return "url(" + relPath + ")";
+ });
+ blob += "\n/* " + sheet + " */\n\n" + code + "\n";
+ }
+ // Pops one sheet off the sheets[] array, reads (and parses if less), and then
+ // recurses again from the async callback until no sheets left, then calls doneCB
+ var readAndParse = function(sheets) {
+ var sheet = sheets.shift();
+ if (sheet) {
+ w(sheet);
+ var isLess = (sheet.slice(-4) == "less");
+ if (isLess && (opt.less !== true)) {
+ sheet = sheet.slice(0, sheet.length-4) + "css";
+ isLess = false;
+ w(" (Substituting CSS: " + sheet + ")");
+ }
+ var code = fs.readFileSync(sheet, "utf8");
+ if (isLess) {
+ var parser = new(less.Parser)({filename:sheet, paths:[path.dirname(sheet)]});
+ parser.parse(code, function (err, tree) {
+ if (err) {
+ console.error(err);
+ } else {
+ addToBlob(sheet, tree.toCSS());
+ }
+ readAndParse(sheets);
+ });
+ } else {
+ addToBlob(sheet, code);
+ readAndParse(sheets);
+ }
+ } else {
+ doneCB(blob);
+ }
+ }
+ readAndParse(loader.sheets);
+};
+
+concatJs = function(loader) {
+ w("");
+ var blob = "";
+ for (var i=0, m; (m=loader.modules[i]); i++) {
+ if (typeof opt.alias === 'undefined' || opt.alias) {
+ w("* inserting path aliases");
+ blob += buildPathBlock(loader);
+ opt.alias = false;
+ }
+ w(m.path);
+ blob += "\n// " + m.rawPath + "\n\n" + compressJsFile(m.path) + "\n";
+ if (opt.alias == m.rawPath) {
+ w("* inserting path aliases");
+ blob += buildPathBlock(loader);
+ }
+ }
+ return blob;
+};
+
+compress = function(inCode) {
+ var ast = jsp.parse(inCode); // parse code and get the initial AST
+ ast = pro.ast_mangle(ast); // get a new AST with mangled names
+ ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
+ return pro.gen_code(ast, {indent_level:0, beautify: !opt.aggro, ascii_only:true}); // compressed code here
+};
+
+compressJsFile = function(inPath) {
+ var code = fs.readFileSync(inPath, "utf8");
+ return compress(code);
+};
+
+finish = function(loader) {
+ //w(loader.packages);
+ //w('');
+ //
+ var output = opt.output || "build";
+ var outfolder = path.dirname(output);
+ var exists = fs.existsSync || path.existsSync;
+ if (outfolder != "." && !exists(outfolder)) {
+ fs.mkdirSync(outfolder);
+ }
+ // Unfortunately, less parsing is asynchronous, so concatCSS is now as well
+ concatCss(loader, function(css) {
+ if (css.length) {
+ w("");
+ fs.writeFileSync(output + ".css", css, "utf8");
+ }
+ //
+ var js = concatJs(loader);
+ /*
+ if (css.length) {
+ js += "\n// " + "minifier: load css" + "\n\n";
+ js += 'enyo.machine.sheet("' + output + '.css");\n';
+ }
+ */
+ if (js.length) {
+ w("");
+ fs.writeFileSync(output + ".js", js, "utf8");
+ }
+ //
+ w("");
+ w("done.");
+ w("");
+
+ // required to properly terminate a
+ // node.process.fork() call, as defined by
+ // <http://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options>
+ process.exit(0);
+ });
+};
+
+var knownOpts = {
+ "alias": Boolean,
+ "enyo": String,
+ "output": String,
+ "help": Boolean
+};
+
+var shortHands = {
+ "alias": ['--alias'],
+ "enyo": ['--enyo'],
+ "output": ['--output'],
+ "h": ['--help'],
+ "?": ['--help'],
+ "help": ['--help']
+};
+
+opt = nopt(knownOpts, shortHands, process.argv, 2);
+opt.source = opt.argv.remain[0];
+w(opt);
+w("");
+
+w("");
+
+if (opt.help) {
+ printUsage();
+ process.exit();
+}
+
+// Send message to parent node process, if any
+process.on('uncaughtException', function (err) {
+ e(err.stack);
+ if (process.send) {
+ // only available if parent-process is node
+ process.send({error: err});
+ }
+ process.exit(1);
+});
+// receive error messages from child node processes
+process.on('message', function(msg) {
+ console.dir(basename, msg);
+ if (msg.error && msg.error.stack) {
+ console.error(basename, msg.error.stack);
+ }
+ if (process.send) {
+ process.send(msg);
+ }
+});
+
+walker.init(opt.enyo);
+walker.walk(opt.source, finish);
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessCHANGELOGmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/CHANGELOG.md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/CHANGELOG.md (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/CHANGELOG.md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+# 1.3.0
+
+2012-03-10
+
+- @media bubbling
+- Support arbitrary entities as selectors
+- [Variadic argument support](https://gist.github.com/1933613)
+- Behaviour of zero-arity mixins has [changed](https://gist.github.com/1933613)
+- Allow `@import` directives in any selector
+- Media-query features can now be a variable
+- Automatic merging of media-query conditions
+- Fix global variable leaks
+- Fix error message on wrong-arity call
+- Fix an `@arguments` behaviour bug
+- Fix `::` selector output
+- Fix a bug when using @media with mixins
+
+
+# 1.2.1
+
+2012-01-15
+
+- Fix imports in browser
+- Improve error reporting in browser
+- Fix Runtime error reports from imported files
+- Fix `File not found` import error reporting
+
+
+# 1.2.0
+
+2012-01-07
+
+- Mixin guards
+- New function `percentage`
+- New `color` function to parse hex color strings
+- New type-checking stylesheet functions
+- Fix Rhino support
+- Fix bug in string arguments to mixin call
+- Fix error reporting when index is 0
+- Fix browser support in WebKit and IE
+- Fix string interpolation bug when var is empty
+- Support `!important` after mixin calls
+- Support vanilla @keyframes directive
+- Support variables in certain css selectors, like `nth-child`
+- Support @media and @import features properly
+- Improve @import support with media features
+- Improve error reports from imported files
+- Improve function call error reporting
+- Improve error-reporting
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessLICENSE"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/LICENSE (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/LICENSE (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/LICENSE 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,179 @@
</span><ins>+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+Copyright (c) 2009-2010 Alexis Sellier
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessMakefile"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/Makefile (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/Makefile (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/Makefile 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,76 @@
</span><ins>+#
+# Run all tests
+#
+test:
+ node test/less-test.js
+
+#
+# Run benchmark
+#
+benchmark:
+ node benchmark/less-benchmark.js
+
+#
+# Build less.js
+#
+SRC = lib/less
+HEADER = build/header.js
+VERSION = `cat package.json | grep version \
+ | grep -o '[0-9]\.[0-9]\.[0-9]\+'`
+DIST = dist/less-${VERSION}.js
+RHINO = dist/less-rhino-${VERSION}.js
+DIST_MIN = dist/less-${VERSION}.min.js
+
+less:
+ @@mkdir -p dist
+ @@touch ${DIST}
+ @@cat ${HEADER} | sed s/@VERSION/${VERSION}/ > ${DIST}
+ @@echo "(function (window, undefined) {" >> ${DIST}
+ @@cat build/require.js\
+ build/ecma-5.js\
+ ${SRC}/parser.js\
+ ${SRC}/functions.js\
+ ${SRC}/colors.js\
+ ${SRC}/tree/*.js\
+ ${SRC}/tree.js\
+ ${SRC}/browser.js\
+ build/amd.js >> ${DIST}
+ @@echo "})(window);" >> ${DIST}
+ @@echo ${DIST} built.
+
+rhino:
+ @@mkdir -p dist
+ @@touch ${RHINO}
+ @@cat build/require-rhino.js\
+ build/ecma-5.js\
+ ${SRC}/parser.js\
+ ${SRC}/functions.js\
+ ${SRC}/colors.js\
+ ${SRC}/tree/*.js\
+ ${SRC}/tree.js\
+ ${SRC}/rhino.js > ${RHINO}
+ @@echo ${RHINO} built.
+
+min: less
+ @@echo minifying...
+ @@uglifyjs ${DIST} > ${DIST_MIN}
+ @@echo ${DIST_MIN} built.
+
+server: less
+ cp dist/less-${VERSION}.js test/html/
+ cd test/html && python -m SimpleHTTPServer
+
+clean:
+ git rm dist/*
+
+dist: clean min
+ git add dist/*
+ git commit -a -m "(dist) build ${VERSION}"
+ git archive master --prefix=less/ -o less-${VERSION}.tar.gz
+ npm publish less-${VERSION}.tar.gz
+
+stable:
+ npm tag less ${VERSION} stable
+
+
+.PHONY: test benchmark
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessREADMEmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/README.md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/README.md (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/README.md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+<b>Note:</b> The Enyo framework currently uses a [fork of Less](https://github.com/enyojs/less.js) with a minor change to [`lib/less/tree/url.js`](https://github.com/enyojs/less.js/blob/master/lib/less/tree/url.js) to ensure that URL paths are propertly rewritten relative to the file that defines the URL when running the node-based compiler used by Enyo's minifier (this is already the default behavior when compiling via the Less.js browser library).
+
+The `dist/less-1.3.0e.js` and `dist/less-1.3.0e.min.js` files are the browser library built from the head of the fork with the single url.js change above.
+
+There is an active conversation happening [here on github](https://github.com/cloudhead/less.js/pull/96) aimed at resolving the inconsistency between the browser and node compilers which the Enyo team is tracking, with the goal of moving back to the less.js master.
+
+===========
+
+less.js
+=======
+
+The **dynamic** stylesheet language.
+
+<http://lesscss.org>
+
+about
+-----
+
+This is the JavaScript, and now official, stable version of LESS.
+
+For more information, visit <http://lesscss.org>.
+
+license
+-------
+
+See `LICENSE` file.
+
+> Copyright (c) 2009-2011 Alexis Sellier
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbenchmarkbenchmarkless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/benchmark/benchmark.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/benchmark/benchmark.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/benchmark/benchmark.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3979 @@
</span><ins>+@bg: #f01;
+@white: #fff;
+@grey: #eee;
+@black: #000;
+@blue: #000;
+@accent_colour: #000;
+@light_grey: #eee;
+@dark_grey: #eee;
+@yellow: #422;
+@red: #ff0000;
+@colour_positive: #ff0000;
+@colour_negative: #ff0000;
+
+.box_shadow (...) {
+}
+.text_shadow (...) {
+}
+.border_radius (...) {
+}
+.border_radius_top_left (...) {
+}
+.border_radius_top_right (...) {
+}
+.border_radius_bottom_right (...) {
+}
+.border_radius_bottom_left (...) {
+}
+.border_radius_top (...) {
+}
+.border_radius_right (...) {
+}
+.border_radius_bottom (...) {
+}
+.border_radius_left (...) {
+}
+div.browse {
+ margin: 0 0 20px;
+ &.class {
+ padding: 0;
+ }
+ div.header {
+ padding: 10px 10px 9px; text-align: left; background: @bg url('/images/panel_header_bg.png') repeat-x top left;
+ border-bottom: 1px solid (@bg * 0.66 + @black * 0.33); line-height: 1; height: 18px;
+ .border_radius_top(3); color: @light_grey;
+ h3 { font-size: 16px; margin: 0; color: @white; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); }
+ span.filter {
+ float: left; display: block; overflow: hidden; position: relative; z-index: 5;
+ a {
+ margin: 0 1px 0 0; display: block; float: left; padding: 0 8px; height: 18px; font-weight: bold; font-size: 10px; line-height: 18px;
+ text-transform: uppercase; background: url('/images/transparent_backgrounds/black_50.png'); color: @light_grey; text-decoration: none; position: relative; z-index: 3;
+ .active {
+ background: @white; color: @black; z-index: 4;
+ :hover { color: @black; }
+ }
+ :hover { color: @white; }
+ :first-child { .border_radius_left(2); }
+ :last-child { .border_radius_right(2); margin-right: 0; }
+ }
+ }
+
+ span.filter.dropdown {
+ margin: 0; position: relative; overflow: visible;
+ a {
+ .border_radius(2); background: @white; color: @black; margin: 0; position: relative; padding-right: 25px;
+ img { float: left; margin: 4px 5px 0 0; }
+ b.arrow {
+ float: right; display: block; height: 0; width: 0; border: 5px solid transparent; border-top: 5px solid @black; border-bottom: none;
+ position: absolute; top: 6px; right: 10px;
+ }
+ :hover {
+ background: @accent_colour; color: @white;
+ b.arrow { border-top: 5px solid @white; }
+ }
+ }
+ ul {
+ position: absolute; top: 100%; left: 0; margin: 1px 0 0; padding: 0; background: @white; .border_radius(2);
+ .box_shadow(0, 1, 1, @black);
+ li {
+ list-style: none; display: block; padding: 0; margin: 0;
+ a {
+ display: block; height: 18px; line-height: 18px; color: @black; font-size: 10px; text-transform: uppercase; background: transparent;
+ border-bottom: 1px solid (@light_grey * 0.66 + @white * 0.33); float: none; margin: 0; .border_radius(0); white-space: nowrap;
+ :hover { background: url('/images/transparent_backgrounds/accent_colour_25.png'); color: @black; }
+ }
+ :last-child {
+ a { border: none; }
+ }
+ }
+ }
+ }
+ span.filter.dropdown.sort { float: left; margin: 0 0 0 10px; }
+ span.filter.dropdown.localisation { float: left; margin: 0 0 0 10px; }
+ a.more {
+ float: right; color: @white; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); font-size: 14px; font-weight: bold;
+ position: relative; top: 2px;
+ :hover { text-decoration: none; }
+ }
+ }
+ > ul {
+ margin: 0; background: @white; padding: 10px 0 0 10px; .border_radius(3); position: relative;
+ li {
+ display: block; float: left; list-style: none; margin: 0 10px 10px 0; padding: 5px; position: relative;
+ background: @white; width: 130px; border: 1px solid (@light_grey * 0.33 + @white * 0.66); .border_radius(2);
+ a.remove {
+ position: absolute; height: 16px; width: 16px; padding: 3px; background: @accent_colour;
+ .border_radius(99); display: none; z-index: 3; top: -8px; right: -8px;
+ img { vertical-align: middle; }
+ }
+ div.thumbnail {
+ .border_radius_top(3); position: relative; z-index: 3;
+ .marker {
+ position: absolute; padding: 2px; .border_radius(2); z-index: 3;
+ background: url('/images/transparent_backgrounds/white_75.png'); height: 12px; width: 12px;
+ }
+ .marker.coupon {
+ height: auto; width: auto; top: 10px; right: -3px; padding: 0; background: transparent; overflow: hidden; position: absolute;
+ b {
+ display: block; height: 0; width: 0; float: left; border: 14px solid transparent; border-top: 14px solid @accent_colour;
+ border-bottom: none; border-right: none; float: left;
+ }
+ span {
+ color: @white; font-size: 10px; font-weight: bold; text-transform: uppercase; height: 14px; line-height: 14px; display: block;
+ padding: 0 4px 0 2px; background: @accent_colour; .text_shadow(1, 1, 0px, (@accent_colour * 0.75 + @black * 0.25)); margin: 0 0 0 14px;
+ }
+ }
+ .marker.video {
+ position: absolute; left: 50%; top: 50%; background: @white; width: 10px; height: 10px;
+ b { display: block; width: 0; height: 0; border: 5px solid transparent; border-left: 10px solid @black; border-right: none; }
+ }
+ .marker.endorsed_by_me { background: none; padding: 0; right: 0; bottom: -32px; .border_radius(2); background: @white; }
+ a.thumbnail {
+ display: block; overflow: hidden; position: relative; text-align: center;
+ img { position: relative; display: block; margin: auto; }
+ }
+ }
+ div.text {
+ margin: 3px 0 0; display: block;
+ a { text-decoration: none; }
+ a.title {
+ display: block; text-decoration: none; font-weight: bold; font-size: 12px; line-height: 16px;
+ white-space: nowrap; height: 16px; overflow: hidden;
+ :before {
+ display: block; height: 32px; width: 20px; content: " "; float: right; right: -15px; top: -8px;
+ background: @white; position: relative; z-index: 1; .box_shadow(-5, 0, 10, @white);
+ }
+ }
+ small {
+ font-size: 11px; line-height: 13px; color: @grey; display: block; height: 13px; overflow: hidden; white-space: nowrap;
+ a { font-weight: bold; }
+ :before {
+ display: block; height: 32px; width: 20px; content: " "; float: right; right: -15px; top: -8px;
+ background: @white; position: relative; z-index: 1; .box_shadow(-5, 0, 10, @white);
+ }
+ }
+ }
+ :hover {
+ background: @accent_colour;
+ a.remove { display: block; }
+ div.thumbnail {
+ a.marker.remove, a.marker.video {
+ b { display: inline-block; }
+ }
+ a.marker.video { .box_shadow(0, 0, 2, @black); }
+ }
+ div.text {
+ a { color: @white; }
+ a.title:before { background: @accent_colour; .box_shadow(-5, 0, 10, @accent_colour); }
+ small {
+ color: @white * 0.75 + @accent_colour * 0.25;
+ :before { background: @accent_colour; .box_shadow(-5, 0, 10, @accent_colour); }
+ }
+ }
+ div.footer a { color: @white; }
+ }
+ }
+ > li.ad div.thumbnail a.thumbnail {
+ width: 130px; height: 97px;
+ img { width: 100%; height: 100%; }
+ }
+ > li.brand div.thumbnail a.thumbnail {
+ width: 120px; height: 87px; padding: 5px; background: @white; .border_radius(2);
+ img { max-width: 120px; max-height: 87px; }
+ }
+ li.paginate {
+ margin-bottom: 0;
+ a {
+ display: block; position: relative; text-decoration: none; height: 131px;
+ div.arrow {
+ background: #81c153 url('/images/button_bg.png') repeat-x left top; border: 1px solid (@accent_colour * 0.75 + @black * 0.25);
+ height: 44px; .border_radius(99); width: 44px; margin: 0 auto; position: relative; top: 32px;
+ b { text-indent: -9000px; display: block; border: 10px solid transparent; width: 0; height: 0; position: relative; top: 12px; }
+ }
+ div.label {
+ position: absolute; bottom: 5px; left: 0; right: 0; line-height: 13px;
+ color: @accent_colour * 0.85 + @black * 0.15; text-decoration: none;
+ font-weight: bold; font-size: 12px; text-align: center;
+ }
+ :hover {
+ div.arrow { background: #abd56e url('/images/button_bg.png') repeat-x left -44px; }
+ }
+ }
+ :hover { background: transparent; }
+ }
+ li.paginate.previous a div b { border-right: 15px solid @white; border-left: none; left: 12px; }
+ li.paginate.next a div b { border-left: 15px solid @white; border-right: none; left: 16px; }
+ }
+ > div.footer {
+ padding: 9px 10px 10px; background: @light_grey * 0.75 + @white * 0.25; overflow: hidden;
+ border-top: 1px solid @light_grey; .border_radius_bottom(3);
+ div.info {
+ float: left; color: @grey;
+ strong { color: @black; font-weight: normal; }
+ }
+ div.pagination {
+ float: right;
+ > * {
+ display: inline-block; line-height: 1; padding: 0 6px; line-height: 18px; height: 18px; background: @white;
+ .border_radius(3); text-decoration: none; font-weight: bold;
+ font-size: 10px; text-transform: uppercase;
+ }
+ a { color: @grey; }
+ a:hover { color: @black; }
+ span.disabled { color: @light_grey; }
+ span.current { color: @white; background: @bg; border: none; }
+ span.current:hover { color: @white; }
+ }
+ }
+}
+div.browse.with_categories { margin: 0 0 0 160px; }
+div.browse.with_options > ul { .border_radius_top(0); }
+div.browse.with_footer > ul { .border_radius_bottom(0); }
+/* Browse List */
+div.browse.list {
+> ul {
+ margin: 0; min-height: 320px;
+ padding: 10px 0 0 10px; overflow: hidden;
+ > li {
+ display: block; list-style: none; margin: 0 10px 10px 0; padding: 5px;
+ .border_radius(3); position: relative; line-height: normal;
+ .marker {
+ position: absolute; padding: 2px; .border_radius(2);
+ background: url('/images/transparent_backgrounds/white_75.png');
+ img { height: 12px; width: 12px; }
+ }
+ img.marker { height: 12px; width: 12px; }
+ span.marker.new {
+ color: black; left: -5px; top: -5px; background: none; background-color: @white * 0.1 + @yellow * 0.6 + @red * 0.3; line-height: 1; padding: 2px 5px;
+ font-weight: bold;
+ }
+ a.marker.media_type {
+ display: inline-block; text-decoration: none; top: 39px; left: 8px;
+ font-size: 10px;
+ b { font-weight: normal; margin: 0 0 0 2px; line-height: 1; display: none; }
+ img { vertical-align: middle; }
+ }
+ a.thumbnail {
+ float: left;
+ width: 68px; display: block; overflow: hidden;
+ border: 1px solid @light_grey;
+ :hover { border-color: @accent_colour; }
+ }
+ span.title_brand {
+ display: block; margin: 0 0 2px 75px;
+ a { margin: 0; display: inline; }
+ a.brand_name { font-weight: normal; font-size: 12px; }
+ }
+ a.ad_title {
+ font-weight: bold; font-size: 14px; margin: 0 0 0 75px; display: block;
+ }
+ a.brand_name {
+ font-weight: bold; font-size: 14px; margin: 0 0 0 75px; display: block;
+ }
+ small {
+ display: block; color: @grey; margin: 0 0 0 75px; font-size: 12px;
+ }
+ small.brand_name { display: inline; margin: 0; }
+ ul.chart {
+ margin: 0 0 0 80px;
+ height: 39px;
+ }
+ ul.networks {
+ margin: 3px 0 0 75px; padding: 0; overflow: hidden;
+ li { display: block; float: left; margin: 0 5px 0 0; line-height: 1; }
+ }
+ div.points {
+ display: none;
+ font-size: 12px; text-align: right;
+ label { color: @grey; }
+ }
+ a.remove { bottom: -3px; right: -3px; }
+ }
+ li.ad {
+ a.thumbnail { height: 51px; }
+ span.title_brand {
+ small.brand_name {
+ display: block;
+ }
+ }
+ }
+ li.brand {
+ a.thumbnail { height: 68px; }
+ }
+ }
+}
+div.browse.list.with_options ul { .border_radius_top(0); }
+div.browse.list.with_footer ul { .border_radius_bottom(0); }
+div.browse.list.cols_2 {
+ > ul {
+ > li {
+ width: 285px; float: left;
+ :hover {
+ background: @white;
+ }
+ }
+ }
+}
+div.browse.ads.list {
+ > ul {
+ > li {
+ height: 53px;
+ a.thumbnail {
+ height: 51px;
+ }
+ }
+ }
+}
+div.browse.brands.list {
+ > ul {
+ > li {
+ height: 68px;
+ a.thumbnail {
+ height: 66px;
+ }
+ }
+ }
+}
+
+/* Categories List */
+#categories {
+ margin: 40px 0 0; width: 160px; float: left; position: relative; z-index: 1;
+ ul {
+ margin: 0; padding: 10px 0 0;
+ li {
+ list-style: none; margin: 0; padding: 0; font-size: 14px;
+ a { color: @grey; display: block; padding: 5px 10px 5px 15px; text-decoration: none; .border_radius_left(3); }
+ a:hover { color: @black; background: @light_grey * 0.15 + @white * 0.85; }
+ }
+ .all a { font-weight: bold; }
+ .current a {
+ background: @white; color: @black; border: 1px solid (@light_grey * 0.25 + @white * 0.75); border-right: none; border-left: 5px solid @bg;
+ padding-left: 10px;
+ }
+ }
+}
+
+/* Ads > Show */
+#ad {
+ div.header {
+ overflow: hidden;
+ h3 { font-size: 16px; margin: 0 0 3px; }
+ small {
+ a.category { font-weight: bold; color: @accent_colour; }
+ span.networks img { position: relative; top: 3px; }
+ }
+ span.brand {
+ float: right; color: @white;
+ a.brand_name { font-weight: bold; color: @accent_colour; }
+ }
+ }
+ div.content {
+ padding: 0; position: relative;
+ a.toggle_size {
+ display: block; .border_radius(3); background-color: @black; padding: 0 5px 0 26px;
+ background-position: 5px center; background-repeat: no-repeat; text-decoration: none; margin: 5px 5px 0 0;
+ position: absolute; top: 0; right: 0; line-height: 25px; z-index: 45;
+ }
+ img.creative { margin: 0 auto; max-width: 540px; display: block; }
+ object { position: relative; z-index: 44; }
+ object.video { line-height: 0; font-size: 0; }
+ object embed { position: relative; z-index: 45; line-height: 0; font-size: 0; }
+ }
+ div.content.not_video {
+ padding: 40px; text-align: center;
+ * { margin-left: auto; margin-right: auto; }
+ object.flash { margin-bottom: 0; }
+ }
+ div.footer {
+ padding: 0;
+ div.vote_views {
+ padding: 5px 10px; overflow: hidden;
+ div.share { float: right; margin: 2px 0 0 0; }
+ #login_register_msg, #encourage_vote_msg { line-height: 22px; font-weight: bold; color: @black; }
+ }
+ }
+}
+#sidebar {
+ #meta {
+ table {
+ margin: 0;
+ tr:last-child td { padding-bottom: 0; }
+ td {
+ padding: 0 0 5px;
+ ul.networks {
+ margin: 0; padding: 0;
+ li {
+ list-style: none; display: inline;
+ }
+ li {
+ }
+ }
+ }
+ td.label { color: @grey; white-space: nowrap; width: 1%; text-align: right; padding-right: 5px; }
+ }
+ }
+}
+
+/* Voting */
+div.voted {
+ font-size: 12px; line-height: 22px; color: @black; display: inline-block; font-weight: bold;
+ img { float: left; margin-right: 5px; padding: 3px; .border_radius(3); }
+}
+#voted_up {
+ img { background: @colour_positive * 0.66 + @bg * 0.15; }
+}
+#voted_down {
+ img { background: @colour_negative * 0.66 + @bg * 0.15; }
+}
+#encourage_comment {
+ display: inline-block; line-height: 22px; font-weight: bold;
+}
+#vote {
+ overflow: hidden; font-size: 12px; line-height: 22px; color: @black; float: left;
+ a {
+ color: @white; font-weight: bold; overflow: hidden; display: block;
+ width: 16px; text-decoration: none; text-align: center; font-size: 10px; padding: 3px; text-transform: uppercase;
+ }
+ a.up {
+ float: left; background: @colour_positive * 0.66 + @bg * 0.15; .border_radius_left(3);
+ :hover { background: @colour_positive * 0.85 + @bg * 0.15; }
+ }
+ a.down {
+ float: left; background: @colour_negative * 0.66 + @bg * 0.15; .border_radius_right(3);
+ margin: 0 5px 0 1px;
+ :hover { background: @colour_negative * 0.85 + @bg * 0.15; }
+ }
+}
+#vote.disabled {
+ a.up {
+ background: (@colour_positive * 0.66 + @bg * 0.15) * 0.15 + @grey * 0.85;
+ :hover { background: (@colour_positive * 0.85 + @bg * 0.15) * 0.25 + @grey * 0.75; }
+ }
+ a.down {
+ background: (@colour_negative * 0.66 + @bg * 0.15) * 0.15 + @grey * 0.85;
+ :hover { background: (@colour_negative * 0.85 + @bg * 0.15) * 0.25 + @grey * 0.75; }
+ }
+}
+
+/* Panels */
+div.panel {
+ margin: 0 0 20px; position: relative; .box_shadow(0, 0, 3, @light_grey * 0.66 + @white * 0.33); .border_radius(3);
+ > div.header {
+ background: @bg url('/images/panel_header_bg.png') repeat-x top left; border-bottom: 1px solid (@bg * 0.66 + @black * 0.33);
+ padding: 5px 10px 4px; .border_radius_top(3); min-height: 18px;
+ h2 { font-size: 16px; margin: 0; color: @white; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); }
+ h3 { color: @white; font-size: 14px; margin: 0; line-height: 18px; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); }
+ small { display: block; font-size: 12px; color: @light_grey * 0.25 + @white * 0.75; }
+ span.filter {
+ float: left; display: block; overflow: hidden; position: relative; z-index: 5;
+ a {
+ margin: 0 1px 0 0; display: block; float: left; padding: 0 8px; height: 18px; font-weight: bold; font-size: 10px; line-height: 18px;
+ text-transform: uppercase; background: url('/images/transparent_backgrounds/black_50.png'); color: @light_grey; text-decoration: none; position: relative; z-index: 3;
+ }
+ a:first-child { .border_radius_left(2); }
+ a:last-child { .border_radius_right(2); margin-right: 0; }
+ a.active { background: @white; color: @black; z-index: 4; }
+ a:hover { color: @white; }
+ a.active:hover { color: @black; }
+ }
+
+ span.filter.dropdown {
+ margin: 0; position: relative; overflow: visible;
+ a {
+ .border_radius(2); background: @white; color: @black; margin: 0; position: relative; padding-right: 25px;
+ img { float: left; margin: 4px 5px 0 0; }
+ b.arrow {
+ float: right; display: block; height: 0; width: 0; border: 5px solid transparent; border-top: 5px solid @black; border-bottom: none;
+ position: absolute; top: 6px; right: 10px;
+ }
+ :hover {
+ background: @accent_colour; color: @white;
+ b.arrow { border-top: 5px solid @white; }
+ }
+ }
+
+ ul {
+ position: absolute; top: 100%; left: 0; margin: 1px 0 0; padding: 0; background: @white; .border_radius(2);
+ .box_shadow(0, 1, 1, @black);
+ li {
+ list-style: none; display: block; padding: 0; margin: 0;
+ a {
+ display: block; height: 18px; line-height: 18px; color: @black; font-size: 10px; text-transform: uppercase; background: transparent;
+ border-bottom: 1px solid (@light_grey * 0.66 + @white * 0.33); float: none; margin: 0; .border_radius(0); white-space: nowrap;
+ :hover { background: url('/images/transparent_backgrounds/accent_colour_25.png'); color: @black; }
+ }
+ }
+ li:last-child {
+ a { border: none; }
+ }
+ }
+ }
+ span.filter.dropdown.sort { float: left; margin: 0 0 0 10px; }
+ span.filter.dropdown.localisation { float: left; margin: 0 0 0 10px; }
+
+ a.more {
+ float: right; color: @white; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); font-size: 14px; font-weight: bold;
+ position: relative; top: 2px;
+ :hover { text-decoration: none; }
+ }
+ }
+ > div.content {
+ background: @white; padding: 10px;
+ .no_padding { padding: 0; }
+ }
+ > div.footer {
+ background: @light_grey * 0.33 + @white * 0.66; border-top: 1px solid (@light_grey * 0.5 + @white * 0.5);
+ padding: 4px 10px 5px; .border_radius_bottom(3);
+ }
+}
+div.panel.no_footer div.content { .border_radius_bottom(3); }
+div.panel.no_header div.content { .border_radius_top(3); }
+div.panel.collapsable {
+ div.header {
+ cursor: pointer;
+ b.toggle { float: right; border: 5px solid transparent; border-bottom: 5px solid @white; border-top: none; display: block; width: 0; height: 0; margin: 6px 0 0 0; }
+ }
+ div.header:hover {
+ background-color: @bg * 0.75 + @white * 0.25;
+ }
+}
+div.panel.collapsed {
+ div.header {
+ border-bottom: none; .border_radius(3);
+ b.toggle { border-bottom: none; border-top: 5px solid @white; }
+ }
+ div.blank { border-bottom: none; .border_radius_bottom(3); }
+ div.content, div.footer { display: none; }
+}
+
+
+/* Sidebar Actions */
+#sidebar {
+ #actions {
+ .box_shadow(0, 0, 0, transparent);
+ div.content {
+ background: url('/images/transparent_backgrounds/accent_colour_10.png'); text-align: center;
+ p.endorsement {
+ margin: 0 0 10px; font-size: 14px; font-weight: bold;
+ small { font-weight: normal; line-height: inherit; margin: 10px 0 0; }
+ :last-child { margin: 0; }
+ }
+ div.share { margin: 5px 0 0; }
+ a.button {
+ font-size: 16px; line-height: normal; height: auto; padding: 5px 10px 5px 35px; font-weight: bold; margin: 0; position: relative;
+ img { position: absolute; top: 3px; left: 6px; }
+ }
+ div.flash.notice {
+ margin: 10px 0 0; font-size: 22px;
+ small { font-weight: normal; margin: 0 0 10px; }
+ }
+ div.flash.notice.done { margin: 0; }
+ small {
+ display: block; margin: 10px 0 0; font-size: 11px; color: #808080; line-height: 12px;
+ img.favicon { vertical-align: middle; }
+ }
+ div.blank {
+ border: none; background: none; padding: 10px 0 0; border-top: 1px solid (@accent_colour * 0.5 + @white * 0.5);
+ margin: 10px 0 0;
+ }
+ }
+ }
+}
+
+/* People Lists */
+ul.people {
+ margin: 0; padding: 10px 0 0 10px; background: @white;
+ > li {
+ display: block; margin: 0 10px 10px 0; float: left; padding: 2px; width: 57px; position: relative;
+ .border_radius(2); background: @white; list-style: none; border: 1px solid (@light_grey * 0.33 + @white * 0.66);
+ a.avatar {
+ display: block; width: 59px; height: 59px; overflow: hidden;
+ img { width: 100%; height: 100%; }
+ }
+ a.name { display: block; font-size: 10px; text-align: center; }
+ :hover {
+ background: @accent_colour;
+ a.name { color: @white; }
+ }
+ }
+}
+ul.people.list {
+ padding: 0;
+ > li {
+ margin: 0 0 10px; padding: 0 0 10px; overflow: hidden; float: none; width: auto; .border_radius(0);
+ border: none; border-bottom: 1px solid (@light_grey * 0.33 + @white * 0.66);
+ span.points {
+ float: right; display: block; padding: 5px; background: @light_grey * 0.15 + @white * 0.85; line-height: 1;
+ text-align: center; width: 50px; height: 30px; .border_radius(3); margin: 0 0 0 10px;
+ strong { display: block; color: @black; font-size: 16px; margin: 2px 0 0; }
+ label { color: @grey; text-transform: uppercase; font-size: 10px; }
+ label.long { display: block; }
+ label.short { display: none; }
+ }
+ a.avatar { float: left; width: 40px; height: 40px; }
+ a.name { font-size: 14px; font-weight: bold; margin: 0 0 0 50px; text-align: left; }
+ a.name.long { display: inline; }
+ a.name.short { display: none; }
+ span.networks {
+ display: block; margin: 0 0 0 50px;
+ img.favicon { vertical-align: middle; }
+ }
+ :hover {
+ background: transparent;
+ a.name { color: @accent_colour * 0.85 + @black * 0.15; }
+ }
+ :last-child { padding-bottom: 0; border-bottom: none; margin-bottom: 0; }
+ }
+}
+ul.people.list.small {
+ > li {
+ span.points {
+ padding: 3px 6px; height: 18px; font-size: 9px; line-height: 17px; width: 60px;
+ strong { font-size: 12px; margin: 0; display: inline; }
+ label { font-size: 9px; }
+ label.long { display: none; }
+ label.short { display: inline; }
+ }
+ a.avatar { width: 24px; height: 24px; }
+ a.name { display: inline; line-height: 24px; margin: 0 0 0 5px; font-size: 12px; height: 24px; }
+ a.name.long { display: none; }
+ a.name.short { display: inline; }
+ span.networks { display: inline; margin: 0; }
+ :last-child { padding-bottom: 0; border-bottom: none; margin-bottom: 0; }
+ }
+}
+ul.people.tiled {
+ > li {
+ width: 28px; padding: 2px;
+ a.avatar { width: 24px; height: 24px; background: @white; padding: 2px; }
+ a.name, small, span.networks, span.points { display: none; }
+ }
+}
+
+/* Comments */
+#comments {
+ ul {
+ margin: 0 0 20px; padding: 0;
+ li {
+ display: block; list-style: none; padding: 0; margin: 0 0 10px;
+ span.meta {
+ margin: 0; overflow: hidden; display: block;
+ small { font-size: 12px; color: @light_grey; float: right; line-height: 16px; display: inline-block; }
+ a.avatar {
+ display: inline-block; height: 16px; width: 16px; position: relative; top: 3px;
+ img { height: 100%; width: 100%; }
+ }
+ a.name { font-weight: bold; line-height: 16px; display: inline-block; }
+ span.inactive { color: @grey; font-weight: bold; line-height: 16px; display: inline-block; }
+ }
+ b.tail {
+ display: block; width: 0; height: 0; margin: 3px 0 0 10px; border: 5px solid transparent; border-top: none;
+ border-bottom: 5px solid @white; position: relative; z-index: 2;
+ }
+ blockquote {
+ margin: 0; padding: 10px; .border_radius(3); font-style: normal; background: @white;
+ color: @dark_grey; .box_shadow(0, 0, 3, @light_grey * 0.66 + @white * 0.33);
+ }
+ }
+ }
+ form {
+ margin: 0;
+ textarea { width: 500px; }
+ }
+}
+
+/* Sidebar Categories */
+#sidebar {
+ #categories {
+ margin: 0 0 20px;
+ width: auto;
+ p { margin: 0; }
+ }
+}
+
+#sidebar {
+ #ads > ul li, #recommendations > ul li {
+ width: 81px;
+ div.thumbnail {
+ a.thumbnail { height: 60px; width: 81px; }
+ }
+ div.text {
+ a.title { font-size: 11px; height: 14px; line-height: 14px; }
+ small { display: none; }
+ }
+ }
+ #brands > ul li {
+ width: 55px;
+ div.thumbnail {
+ a.thumbnail {
+ height: 45px; width: 45px;
+ img { max-height: 45px; max-width: 45px; }
+ }
+ }
+ div.text { display: none; }
+ }
+}
+
+/* My Account */
+#accounts_controller {
+ #top {
+ #page_title {
+ #page_options {
+ a.button.public_profile {
+ float: right; font-size: 16px; line-height: 1; height: auto; padding: 8px 35px 8px 15px; position: relative;
+ b.arrow { display: block; height: 0; width: 0; position: absolute; top: 10px; right: 15px; border: 6px solid transparent; border-right: none; border-left: 6px solid @white; margin: 0; }
+ }
+ a.button.goto_dashboard {
+ float: right; font-size: 16px; line-height: 1; height: auto; padding: 8px 15px 8px 35px; margin-right: 5px; position: relative;
+ b.arrow { display: block; height: 0; width: 0; position: absolute; top: 10px; left: 15px; border: 6px solid transparent; border-left: none; border-right: 6px solid @white; margin: 0; }
+ }
+ }
+ }
+ }
+ #account_nav {
+ float: left; width: 200px; margin: 0 20px 0 0;
+ ul.nav {
+ margin: 0; padding: 0;
+ li {
+ margin: 0 0 5px; display: block; list-style: none; padding: 0;
+ a {
+ display: block; height: 30px; text-decoration: none; color: @white;
+ b {
+ border: 15px solid transparent; border-right: none; border-left: 10px solid transparent; width: 0;
+ height: 0; float: right; display: none;
+ }
+ span {
+ .border_radius(3); background: @bg; display: block;
+ line-height: 30px; padding: 0 10px; font-size: 14px; font-weight: bold; margin: 0 10px 0 0;
+ }
+ }
+ :hover {
+ a {
+ color: @white;
+ b { border-left-color: @bg; display: block; }
+ span { background: @bg; .border_radius_right(0); }
+ }
+ }
+ }
+ li.current a {
+ b { border-left-color: @accent_colour; display: block; }
+ span { background: @accent_colour; color: @white; .border_radius_right(0); }
+ }
+ }
+ }
+ #main {
+ > div {
+ margin: 0 0 20px;
+ form { margin: 0; }
+ }
+ #profile {
+ a.avatar {
+ float: left; display: block;
+ width: 70px; overflow: hidden; position: relative; text-decoration: none;
+ img { width: 100%; }
+ span {
+ display: block; line-height: 1; padding: 3px; margin: 5px 0 0; color: @white; background: @accent_colour;
+ .border_radius(3); .text_shadow(1, 1, 0, @grey);
+ text-align: center; font-size: 10px; font-weight: bold; text-transform: uppercase;
+ }
+ }
+ form {
+ margin: 0 0 0 90px;
+ h4 { margin: 10px 0 20px; border-bottom: 1px solid (@light_grey * 0.5 + @white * 0.5); padding: 0; color: @bg; font-size: 16px; }
+ ul.choices {
+ li { width: 30%; }
+ }
+ div.extra { margin-top: 20px; }
+ }
+ }
+
+ #networks {
+ ul { margin: 0 -10px -10px 0; padding: 0; overflow: hidden;
+ li:hover
+ {
+ background: @light_grey; display: block; float: left; width: 180px;
+ padding: 10px; margin: 0 10px 10px 0; list-style: none; .border_radius(3);
+ position: relative;
+ * { line-height: normal; }
+ img { vertical-align: middle; float: left; }
+ .name { font-weight: bold; font-size: 14px; display: block; margin: -2px 0 0 42px; }
+ small {
+ font-size: 12px; color: @grey; display: block; margin-left: 42px;
+ strong { color: @black; font-weight: normal; }
+ }
+ :hover {
+ }
+ }
+ li.installed {
+ background: @white;
+ border: 2px solid @accent_colour; padding: 8px;
+ }
+ li.unavailable {
+ .name { color: @black; }
+ :hover {
+ background: @light_grey;
+ }
+ }
+ li:hover {
+ background: @light_grey * 0.5 + @white * 0.5;
+ }
+ }
+ }
+ }
+}
+
+/* Shopping Style Panel */
+#shopping_style {
+ div.header a.button.small { float: right; }
+ div.content {
+ p {
+ margin: 0 0 10px;
+ label { text-transform: uppercase; font-size: 11px; display: block; color: @bg; font-weight: bold; }
+ span { color: @black; }
+ span.toggle { white-space: nowrap; color: @grey; }
+ :last-child { margin: 0; }
+ }
+ p.more { text-align: left; font-weight: normal; }
+ p.less { display: none; margin: 0; }
+ }
+}
+
+/* People Controller */
+#people_controller.index {
+ #main {
+ div.panel {
+ float: left; width: 300px; margin: 0 20px 0 0;
+ :last-child { margin-right: 0; }
+ }
+ }
+}
+#people_controller.show {
+ #person_overview, #shopping_style {
+ a.button.small {
+ }
+ }
+ #content {
+ #shopping_style {
+ float: left; width: 240px; margin: 0 20px 0 0;
+ }
+ #main { width: 360px; }
+ }
+}
+
+/* Search Results */
+#search_results {
+ margin: 0 0 20px;
+ li {
+ :hover {
+ small { color: @white * 0.75 + @accent_colour * 0.25; }
+ }
+ }
+}
+#search {
+ div.content {
+ padding: 20px;
+ form {
+ margin: 0; float: none;
+ span.submit_and_options {
+ display: block;
+ }
+ }
+ p { margin: 0 0 15px; }
+ h4 { font-weight: normal; margin: 0 0 5px; }
+ }
+}
+
+/* Recommendations */
+#recommendations {
+ div.browse {
+ margin: 0; padding: 0; background: none;
+ ul { min-height: 0; .border_radius(0); }
+ }
+}
+
+/* Blank States */
+div.blank {
+ padding: 20px; background: @bg * 0.05 + @blue * 0.05 + @white * 0.9; position: relative;
+ border: 1px solid (@bg * 0.1 + @blue * 0.1 + @white * 0.8); z-index: 1;
+ h4 { font-size: 18px; margin: 0 0 10px; }
+ h4:last-child { margin: 0; }
+ p { font-size: 16px; margin: 0 0 10px; }
+ p:last-child { margin: 0; }
+ p.with_list_number.large {
+ span { margin-left: 48px; display: block; color: @white; }
+ }
+ p.earn span { font-size: 22px; color: @white; line-height: 48px; font-weight: bold; }
+ a { white-space: nowrap; }
+ a.hide {
+ position: absolute; top: -5px; right: -5px; display: block; height: 16px; width: 16px; padding: 3px; background: #E7E9F6; .border_radius(99);
+ }
+}
+
+div.blank.small {
+ padding: 10px 20px;
+ h4 { font-weight: normal; font-size: 16px; }
+ p { margin: 0; }
+}
+div.blank.tiny {
+ padding: 10px 20px;
+ h4 { font-weight: normal; font-size: 14px; }
+ p { margin: 0; font-size: 12px; }
+}
+div.blank.rounded {
+ .border_radius(3); margin: 0 0 20px;
+}
+div.blank.rounded.bottom { .border_radius_top(0); }
+div.blank.with_border_bottom { border-bottom: 1px solid (@bg * 0.1 + @blue * 0.1 + @white * 0.8); }
+div.blank.no_border_top { border-top: none; }
+div.blank.no_border_bottom { border-bottom: none; }
+div.blank.no_side_borders { border-right: none; border-left: none; }
+div.panel {
+ div.blank {
+ padding: 10px 20px; overflow: hidden; margin: 0;
+ h4 { font-weight: normal; font-size: 14px; }
+ p, ul { margin: 0 0 10px; font-size: 12px; }
+ p:last-child, ul:last-child { margin: 0; }
+ }
+}
+
+/* Sidebar Browse */
+#sidebar {
+ div.panel {
+ div.content.browse {
+ padding: 0; margin: 0;
+ > ul {
+ min-height: 0; .border_radius(0);
+ > li {
+ div.thumbnail {
+ a.thumbnail { padding: 5px; }
+ img.marker.media_type { top: 48px; left: 8px; }
+ }
+ div.footer {
+ a.title, a.name { font-size: 11px; font-weight: normal; }
+ }
+ }
+ }
+ }
+
+ div.content.browse.ads > ul > li {
+ width: 93px;
+ > div.thumbnail a.thumbnail { width: 83px; height: 62px; }
+ }
+ div.content.browse.brands {
+ .border_radius(3);
+ > ul {
+ background: none;
+ > li {
+ width: 52px;
+ > div.thumbnail {
+ padding: 3px;
+ a.thumbnail { width: 42px; height: 42px; padding: 2px; }
+ }
+ li.active { background: @accent_colour; }
+ }
+ }
+ }
+ div.footer {
+ div.info { float: none; }
+ div.pagination { float: none; margin: 3px 0 0; }
+ }
+ }
+}
+
+/* List Numbers */
+label.list_number {
+ float: left; background: url('/images/transparent_backgrounds/black_15.png'); padding: 2px; width: 24px; height: 24px; display: block;
+ .border_radius(99);
+ b {
+ display: block; font-weight: bold; font-size: 14px; color: @white; background: @accent_colour; height: 20px; width: 20px; line-height: 20px;
+ text-align: center; .border_radius(99); .text_shadow(1, 1, 0px, (@accent_colour * 0.75 + @black * 0.25));
+ border: 2px solid @white;
+ }
+}
+label.list_number.large {
+ padding: 4px; width: 48px; height: 48px; .border_radius(99); position: relative; left: -10px;
+ b {
+ font-size: 28px; height: 40px; width: 40px; .border_radius(99); line-height: 40px;
+ .text_shadow(2, 2, 0px, (@accent_colour * 0.75 + @black * 0.25)); border-width: 4px;
+ }
+}
+
+/* Dashboard */
+#dashboard_controller {
+ #ads {
+ span.filter.state { float: right; }
+ }
+ #sidebar {
+ #shopping_style div.content {
+ p.less { display: block; }
+ p.more { display: none; }
+ }
+ #influences {
+ div.header {
+ padding-bottom: 0;
+ ul.tabs {
+ position: relative; top: 1px; z-index: 3;
+ li {
+ margin: 0 5px 0 0;
+ a {
+ border: none; background: url('/images/transparent_backgrounds/white_75.png');
+ :hover { color: @black; }
+ }
+ }
+ li.active {
+ a {
+ background: @white; border: none;
+ :hover { color: @black; }
+ }
+ }
+ }
+ }
+
+ div.tab_content {
+ overflow: hidden; padding: 0;
+ > ul {
+ padding: 10px 10px 0; max-height: 280px; min-height: 120px; overflow-y: scroll; .border_radius_bottom(3px);
+ }
+ }
+ div.footer {
+ form {
+ p {
+ margin: 0 0 5px;
+ img.marker { float: right; margin: 5px 0 0 0; }
+ span.invitee {
+ line-height: 26px; padding: 3px 3px 0; font-size: 14px;
+ small { color: @grey; font-size: 12px; }
+ }
+ }
+ p.indent { margin-left: 36px; }
+ p.submit { margin-top: 10px; }
+ }
+ }
+ }
+ }
+
+ div.panel.full {
+ > div.content {
+ margin: 0; padding: 0; background: none;
+ ul {
+ li {
+ width: 148px;
+ div.thumbnail {
+ img.marker.media_type { top: 90px; }
+ a.thumbnail { width: 138px; height: 104px; }
+ }
+ }
+ }
+ }
+ }
+ #people {
+ form {
+ padding: 0 0 5px;
+ input { width: 225px; float: left; margin: 0 5px 0 0; }
+ a.button { height: 23px; line-height: 23px; width: 60px; padding: 0; text-align: center; }
+ }
+ }
+}
+
+/* Remove Pages Titles when Browsing */
+#ads_controller, #brands_controller {
+ #page_title { display: none; }
+}
+
+/* Brands > Show */
+#brands_controller.show {
+ #ads {
+ div.filters {
+ h3 { font-size: 16px; margin: 0; }
+ span.show { float: right; }
+ span.filter.dropdown.localisation { float: right; margin: 0 0 0 10px; }
+ span.filter.state { float: right; margin: 0 0 0 10px; }
+ }
+ }
+}
+
+/* FAQ */
+#pages_controller.faq {
+ #answers {
+ h3 { margin-top: 20px; padding-top: 20px; border-top: 1px solid (@light_grey * 0.75 + @white * 0.25); }
+ h3.first { margin-top: 0; padding-top: 0; border: none; }
+ }
+ #questions {
+ div.content {
+ padding: 20px;
+ ul {
+ margin: 0; padding: 0;
+ li {
+ margin: 0 0 10px; list-style: none; display: block; padding: 0;
+ a { font-size: 14px; }
+ }
+ li:last-child {
+ margin: 0;
+ }
+ }
+ }
+ }
+}
+
+/* Person Overview */
+#person_overview {
+ padding: 20px 10px; position: relative; z-index: 25;
+ #person {
+ float: left; width: 620px;
+ a.avatar {
+ display: block; float: left; width: 60px; height: 60px;
+ img { height: 100%; width: 100%; }
+ }
+ > div {
+ margin: 0 0 0 75px; color: @white; font-size: 14px; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33);
+ }
+ div.name {
+ h2 {
+ margin: 0 0 5px; display: inline;
+ a {
+ font-size: 20px; font-weight: bold; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33);
+ line-height: 1; color: @white; text-decoration: none;
+ :hover { text-decoration: underline; }
+ }
+ a.button.small {
+ font-size: 10px;
+ :hover { text-decoration: none; }
+ }
+ }
+
+ span.points {
+ float: right; display: block; padding: 5px 10px; .border_radius(2); text-align: center; background: @white; position: relative;
+ min-width: 45px;
+ strong { color: @black; font-weight: bold; font-size: 24px; line-height: 1; display: block; .text_shadow(0, 0, 0, transparent); }
+ label { font-size: 9px; text-transform: uppercase; color: @grey; display: block; .text_shadow(0, 0, 0, transparent); font-weight: bold; }
+ }
+ span.points.with_redeem {
+ .border_radius_bottom(0);
+ a.button {
+ display: block; text-align: center; .border_radius_top(0); font-size: 10px; font-weight: bold; padding: 0;
+ position: absolute; height: 18px; left: 0; right: 0; bottom: -19px; line-height: 18px; text-transform: uppercase; border: none;
+ }
+ }
+ div.options { margin: 0; }
+ }
+ div.meta {
+ color: @white * 0.66 + @bg * 0.33;
+ span { color: @white; }
+ label { color: @white * 0.66 + @bg * 0.33; }
+ ul.networks {
+ display: inline; margin: 0; padding: 0;
+ li {
+ display: inline; line-height: 1;
+ img { position: relative; vertical-align: middle; top: -1px; }
+ }
+ }
+ }
+
+ div.extra {
+ font-size: 12px; margin-top: 20px; margin-bottom: 20px;
+ span.toggle {
+ .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33);
+ a { font-size: 10px; font-weight: bold; text-transform: uppercase; text-decoration: none; color: @accent_colour; }
+ b.arrow { display: inline-block; width: 0; height: 0; border: 5px solid transparent; position: relative; top: -2px; }
+ }
+ #less_info {
+ span.toggle {
+ b.arrow { border-top: 5px solid @accent_colour; border-bottom: 0; }
+ }
+ }
+ #more_info {
+ span.toggle {
+ float: right;
+ b.arrow { border-bottom: 5px solid @accent_colour; border-top: 0; }
+ }
+ h4 {
+ color: @white; margin: 0 0 10px 0; border-bottom: 1px solid (@white * 0.25 + @bg * 0.75); .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33);
+ span { font-size: 12px; }
+ }
+ p {
+ margin: 0 0 5px;
+ label { display: block; float: left; width: 120px; color: @white * 0.66 + @bg * 0.33; }
+ span { display: block; margin: 0 0 0 130px; }
+ }
+ p:last-child { margin: 0; }
+
+ }
+ }
+ div.login {
+ margin: 0 0 0 75px;
+ a.button { font-weight: bold; }
+ }
+ }
+}
+
+/* Dashboard Nav */
+#dashboard_nav {
+ position: absolute; bottom: 0; left: 10px; margin: 0; padding: 0; overflow: hidden;
+ li {
+ display: block; float: left; margin: 0 5px 0 0;
+ a {
+ display: block; height: 28px; padding: 0 10px; line-height: 28px; .border_radius_top(2);
+ text-decoration: none; color: @white; background: url('/images/transparent_backgrounds/accent_colour_30.png'); font-size: 14px;
+ font-weight: bold;
+ :hover { background: url('/images/transparent_backgrounds/accent_colour_45.png'); }
+ }
+ }
+ li.active {
+ a {
+ background: @white; color: @black;
+ :hover { color: @black; }
+ }
+ }
+}
+
+/* Dwellometer */
+#dwellometer {
+ z-index: 45; float: right; .box_shadow(0, 0, 0, transparent); margin: 0;
+ div.content {
+ text-align: center; position: relative;
+ object, object embed { position: relative; z-index: 46; line-height: 0; }
+ div.title {
+ position: absolute; bottom: 10px; left: 0; right: 0; z-index: 50;
+ img { width: 120px; display: block; margin: 0 auto; position: relative; left: -5px; }
+ }
+ }
+}
+
+/* Activity Stream */
+#activity {
+ div.content {
+ ul.events {
+ padding: 0; margin: 0 0 -10px;
+ li {
+ margin: 0; padding: 10px 0; border-bottom: 1px solid (@light_grey * 0.33 + @white * 0.66);
+ list-style: none; overflow: hidden;
+ small.meta {
+ font-size: 12px; color: @light_grey; float: right;
+ }
+ a.button { float: right; margin: 0 0 10px 10px; }
+ a.avatar, a.logo, a.thumbnail {
+ height: 32px; display: block; float: left;
+ img { width: 100%; height: 100%; }
+ }
+ a.avatar, a.logo, a.icon { width: 32px; }
+ a.thumbnail { width: 42px; }
+ div.symbols {
+ float: left; overflow: hidden;
+ b {
+ display: block; float: left; margin: 10px 5px 0;
+ img { height: 12px; width: 12px; }
+ }
+ b.voted { margin: 10px 3px 0; padding: 2px; .border_radius(2); }
+ b.voted.for { background: @colour_positive * 0.33 + @white * 0.66; }
+ b.voted.against { background: @colour_negative * 0.33 + @white * 0.66; }
+ }
+ /* Temporarily removed avatar and symbol */
+/* div.symbols a.agent, b { display: none; }*/
+ div.description {
+ font-size: 12px; color: @grey;
+ a.agent { font-weight: bold; }
+ }
+ div.comment {
+ margin-top: 2px;
+ b.tail {
+ display: block; margin: 0 0 0 10px; width: 0; height: 0; border: 5px solid transparent;
+ border-top: none; border-bottom: 5px solid (@light_grey * 0.25 + @white * 0.75);
+ }
+ blockquote {
+ margin: 0; font-style: normal; color: @dark_grey;
+ .border_radius(3); background: @light_grey * 0.25 + @white * 0.75; padding: 5px 10px;
+ span.view_comment {
+ color: @grey;
+ }
+ }
+ }
+ div.content {
+ overflow: hidden;
+ }
+ }
+ li.new_comment.ad, li.endorsed.ad, li.voted {
+ div.description, div.content { margin-left: 106px; }
+/* div.description, div.content { margin-left: 53px; }*/
+ }
+ li.new_comment.brand, li.replied_to, li.endorsed.brand, li.connected, li.sn_setup {
+ div.description, div.content { margin-left: 96px; }
+/* div.description, div.content { margin-left: 43px; }*/
+ }
+ li.replied_to {
+ div.content {
+ a.thumbnail, a.logo { margin-top: 7px; }
+ }
+ }
+ li.replied_to.ad {
+ div.content {
+ div.comment { margin-left: 52px; }
+ }
+ }
+ li.replied_to.brand {
+ div.content {
+ div.comment { margin-left: 42px; }
+ }
+ }
+ li.voted div.description span.action { .border_radius(2); color: @dark_grey; padding: 0 3px; white-space: nowrap; }
+ li.voted.for div.description span.action { background: @colour_positive * 0.15 + @white * 0.85; }
+ li.voted.against div.description span.action { background: @colour_negative * 0.15 + @white * 0.85; }
+ li:first-child { padding-top: 0; }
+ li:last-child { border-bottom: none; }
+ li:hover div.content div.comment blockquote span.view_comment {
+ }
+ }
+ }
+}
+
+/* Login/Register Modal */
+#login_register {
+ div.location_select,
+ div.location_search { margin-left: 130px; }
+ h3 {
+ small { font-size: 14px; font-weight: normal; display: block; color: @grey; text-align: left; margin: 0; display: block; }
+ }
+}
+
+/* Contact Form in Pages */
+#pages_controller {
+ #sidebar {
+ #contact {
+ margin: 15px 0 0;
+ form {
+ label { text-align: left; float: none; width: auto; font-size: 12px; font-weight: bold; line-height: 1; margin: 0 0 5px; }
+ p.submit.indent {
+ margin: 0;
+ span.with_cancel { display: none; }
+ }
+ }
+ }
+ }
+}
+
+/* Exclusive Offers */
+#offers {
+ div.content {
+ a.gift {
+ display: block; text-align: center;
+ img { height: 100px; }
+ }
+ }
+}
+
+div.browse {
+ margin: 0 0 20px;
+ &.class {
+ padding: 0;
+ }
+ div.header {
+ padding: 10px 10px 9px; text-align: left; background: @bg url('/images/panel_header_bg.png') repeat-x top left;
+ border-bottom: 1px solid (@bg * 0.66 + @black * 0.33); line-height: 1; height: 18px;
+ .border_radius_top(3); color: @light_grey;
+ h3 { font-size: 16px; margin: 0; color: @white; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); }
+ span.filter {
+ float: left; display: block; overflow: hidden; position: relative; z-index: 5;
+ a {
+ margin: 0 1px 0 0; display: block; float: left; padding: 0 8px; height: 18px; font-weight: bold; font-size: 10px; line-height: 18px;
+ text-transform: uppercase; background: url('/images/transparent_backgrounds/black_50.png'); color: @light_grey; text-decoration: none; position: relative; z-index: 3;
+ .active {
+ background: @white; color: @black; z-index: 4;
+ :hover { color: @black; }
+ }
+ :hover { color: @white; }
+ :first-child { .border_radius_left(2); }
+ :last-child { .border_radius_right(2); margin-right: 0; }
+ }
+ }
+
+ span.filter.dropdown {
+ margin: 0; position: relative; overflow: visible;
+ a {
+ .border_radius(2); background: @white; color: @black; margin: 0; position: relative; padding-right: 25px;
+ img { float: left; margin: 4px 5px 0 0; }
+ b.arrow {
+ float: right; display: block; height: 0; width: 0; border: 5px solid transparent; border-top: 5px solid @black; border-bottom: none;
+ position: absolute; top: 6px; right: 10px;
+ }
+ :hover {
+ background: @accent_colour; color: @white;
+ b.arrow { border-top: 5px solid @white; }
+ }
+ }
+ ul {
+ position: absolute; top: 100%; left: 0; margin: 1px 0 0; padding: 0; background: @white; .border_radius(2);
+ .box_shadow(0, 1, 1, @black);
+ li {
+ list-style: none; display: block; padding: 0; margin: 0;
+ a {
+ display: block; height: 18px; line-height: 18px; color: @black; font-size: 10px; text-transform: uppercase; background: transparent;
+ border-bottom: 1px solid (@light_grey * 0.66 + @white * 0.33); float: none; margin: 0; .border_radius(0); white-space: nowrap;
+ :hover { background: url('/images/transparent_backgrounds/accent_colour_25.png'); color: @black; }
+ }
+ :last-child {
+ a { border: none; }
+ }
+ }
+ }
+ }
+ span.filter.dropdown.sort { float: left; margin: 0 0 0 10px; }
+ span.filter.dropdown.localisation { float: left; margin: 0 0 0 10px; }
+ a.more {
+ float: right; color: @white; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); font-size: 14px; font-weight: bold;
+ position: relative; top: 2px;
+ :hover { text-decoration: none; }
+ }
+ }
+ > ul {
+ margin: 0; background: @white; padding: 10px 0 0 10px; .border_radius(3); position: relative;
+ li {
+ display: block; float: left; list-style: none; margin: 0 10px 10px 0; padding: 5px; position: relative;
+ background: @white; width: 130px; border: 1px solid (@light_grey * 0.33 + @white * 0.66); .border_radius(2);
+ a.remove {
+ position: absolute; height: 16px; width: 16px; padding: 3px; background: @accent_colour;
+ .border_radius(99); display: none; z-index: 3; top: -8px; right: -8px;
+ img { vertical-align: middle; }
+ }
+ div.thumbnail {
+ .border_radius_top(3); position: relative; z-index: 3;
+ .marker {
+ position: absolute; padding: 2px; .border_radius(2); z-index: 3;
+ background: url('/images/transparent_backgrounds/white_75.png'); height: 12px; width: 12px;
+ }
+ .marker.coupon {
+ height: auto; width: auto; top: 10px; right: -3px; padding: 0; background: transparent; overflow: hidden; position: absolute;
+ b {
+ display: block; height: 0; width: 0; float: left; border: 14px solid transparent; border-top: 14px solid @accent_colour;
+ border-bottom: none; border-right: none; float: left;
+ }
+ span {
+ color: @white; font-size: 10px; font-weight: bold; text-transform: uppercase; height: 14px; line-height: 14px; display: block;
+ padding: 0 4px 0 2px; background: @accent_colour; .text_shadow(1, 1, 0px, (@accent_colour * 0.75 + @black * 0.25)); margin: 0 0 0 14px;
+ }
+ }
+ .marker.video {
+ position: absolute; left: 50%; top: 50%; background: @white; width: 10px; height: 10px;
+ b { display: block; width: 0; height: 0; border: 5px solid transparent; border-left: 10px solid @black; border-right: none; }
+ }
+ .marker.endorsed_by_me { background: none; padding: 0; right: 0; bottom: -32px; .border_radius(2); background: @white; }
+ a.thumbnail {
+ display: block; overflow: hidden; position: relative; text-align: center;
+ img { position: relative; display: block; margin: auto; }
+ }
+ }
+ div.text {
+ margin: 3px 0 0; display: block;
+ a { text-decoration: none; }
+ a.title {
+ display: block; text-decoration: none; font-weight: bold; font-size: 12px; line-height: 16px;
+ white-space: nowrap; height: 16px; overflow: hidden;
+ :before {
+ display: block; height: 32px; width: 20px; content: " "; float: right; right: -15px; top: -8px;
+ background: @white; position: relative; z-index: 1; .box_shadow(-5, 0, 10, @white);
+ }
+ }
+ small {
+ font-size: 11px; line-height: 13px; color: @grey; display: block; height: 13px; overflow: hidden; white-space: nowrap;
+ a { font-weight: bold; }
+ :before {
+ display: block; height: 32px; width: 20px; content: " "; float: right; right: -15px; top: -8px;
+ background: @white; position: relative; z-index: 1; .box_shadow(-5, 0, 10, @white);
+ }
+ }
+ }
+ :hover {
+ background: @accent_colour;
+ a.remove { display: block; }
+ div.thumbnail {
+ a.marker.remove, a.marker.video {
+ b { display: inline-block; }
+ }
+ a.marker.video { .box_shadow(0, 0, 2, @black); }
+ }
+ div.text {
+ a { color: @white; }
+ a.title:before { background: @accent_colour; .box_shadow(-5, 0, 10, @accent_colour); }
+ small {
+ color: @white * 0.75 + @accent_colour * 0.25;
+ :before { background: @accent_colour; .box_shadow(-5, 0, 10, @accent_colour); }
+ }
+ }
+ div.footer a { color: @white; }
+ }
+ }
+ > li.ad div.thumbnail a.thumbnail {
+ width: 130px; height: 97px;
+ img { width: 100%; height: 100%; }
+ }
+ > li.brand div.thumbnail a.thumbnail {
+ width: 120px; height: 87px; padding: 5px; background: @white; .border_radius(2);
+ img { max-width: 120px; max-height: 87px; }
+ }
+ li.paginate {
+ margin-bottom: 0;
+ a {
+ display: block; position: relative; text-decoration: none; height: 131px;
+ div.arrow {
+ background: #81c153 url('/images/button_bg.png') repeat-x left top; border: 1px solid (@accent_colour * 0.75 + @black * 0.25);
+ height: 44px; .border_radius(99); width: 44px; margin: 0 auto; position: relative; top: 32px;
+ b { text-indent: -9000px; display: block; border: 10px solid transparent; width: 0; height: 0; position: relative; top: 12px; }
+ }
+ div.label {
+ position: absolute; bottom: 5px; left: 0; right: 0; line-height: 13px;
+ color: @accent_colour * 0.85 + @black * 0.15; text-decoration: none;
+ font-weight: bold; font-size: 12px; text-align: center;
+ }
+ :hover {
+ div.arrow { background: #abd56e url('/images/button_bg.png') repeat-x left -44px; }
+ }
+ }
+ :hover { background: transparent; }
+ }
+ li.paginate.previous a div b { border-right: 15px solid @white; border-left: none; left: 12px; }
+ li.paginate.next a div b { border-left: 15px solid @white; border-right: none; left: 16px; }
+ }
+ > div.footer {
+ padding: 9px 10px 10px; background: @light_grey * 0.75 + @white * 0.25; overflow: hidden;
+ border-top: 1px solid @light_grey; .border_radius_bottom(3);
+ div.info {
+ float: left; color: @grey;
+ strong { color: @black; font-weight: normal; }
+ }
+ div.pagination {
+ float: right;
+ > * {
+ display: inline-block; line-height: 1; padding: 0 6px; line-height: 18px; height: 18px; background: @white;
+ .border_radius(3); text-decoration: none; font-weight: bold;
+ font-size: 10px; text-transform: uppercase;
+ }
+ a { color: @grey; }
+ a:hover { color: @black; }
+ span.disabled { color: @light_grey; }
+ span.current { color: @white; background: @bg; border: none; }
+ span.current:hover { color: @white; }
+ }
+ }
+}
+div.browse.with_categories { margin: 0 0 0 160px; }
+div.browse.with_options > ul { .border_radius_top(0); }
+div.browse.with_footer > ul { .border_radius_bottom(0); }
+/* Browse List */
+div.browse.list {
+> ul {
+ margin: 0; min-height: 320px;
+ padding: 10px 0 0 10px; overflow: hidden;
+ > li {
+ display: block; list-style: none; margin: 0 10px 10px 0; padding: 5px;
+ .border_radius(3); position: relative; line-height: normal;
+ .marker {
+ position: absolute; padding: 2px; .border_radius(2);
+ background: url('/images/transparent_backgrounds/white_75.png');
+ img { height: 12px; width: 12px; }
+ }
+ img.marker { height: 12px; width: 12px; }
+ span.marker.new {
+ color: black; left: -5px; top: -5px; background: none; background-color: @white * 0.1 + @yellow * 0.6 + @red * 0.3; line-height: 1; padding: 2px 5px;
+ font-weight: bold;
+ }
+ a.marker.media_type {
+ display: inline-block; text-decoration: none; top: 39px; left: 8px;
+ font-size: 10px;
+ b { font-weight: normal; margin: 0 0 0 2px; line-height: 1; display: none; }
+ img { vertical-align: middle; }
+ }
+ a.thumbnail {
+ float: left;
+ width: 68px; display: block; overflow: hidden;
+ border: 1px solid @light_grey;
+ :hover { border-color: @accent_colour; }
+ }
+ span.title_brand {
+ display: block; margin: 0 0 2px 75px;
+ a { margin: 0; display: inline; }
+ a.brand_name { font-weight: normal; font-size: 12px; }
+ }
+ a.ad_title {
+ font-weight: bold; font-size: 14px; margin: 0 0 0 75px; display: block;
+ }
+ a.brand_name {
+ font-weight: bold; font-size: 14px; margin: 0 0 0 75px; display: block;
+ }
+ small {
+ display: block; color: @grey; margin: 0 0 0 75px; font-size: 12px;
+ }
+ small.brand_name { display: inline; margin: 0; }
+ ul.chart {
+ margin: 0 0 0 80px;
+ height: 39px;
+ }
+ ul.networks {
+ margin: 3px 0 0 75px; padding: 0; overflow: hidden;
+ li { display: block; float: left; margin: 0 5px 0 0; line-height: 1; }
+ }
+ div.points {
+ display: none;
+ font-size: 12px; text-align: right;
+ label { color: @grey; }
+ }
+ a.remove { bottom: -3px; right: -3px; }
+ }
+ li.ad {
+ a.thumbnail { height: 51px; }
+ span.title_brand {
+ small.brand_name {
+ display: block;
+ }
+ }
+ }
+ li.brand {
+ a.thumbnail { height: 68px; }
+ }
+ }
+}
+div.browse.list.with_options ul { .border_radius_top(0); }
+div.browse.list.with_footer ul { .border_radius_bottom(0); }
+div.browse.list.cols_2 {
+ > ul {
+ > li {
+ width: 285px; float: left;
+ :hover {
+ background: @white;
+ }
+ }
+ }
+}
+div.browse.ads.list {
+ > ul {
+ > li {
+ height: 53px;
+ a.thumbnail {
+ height: 51px;
+ }
+ }
+ }
+}
+div.browse.brands.list {
+ > ul {
+ > li {
+ height: 68px;
+ a.thumbnail {
+ height: 66px;
+ }
+ }
+ }
+}
+
+/* Categories List */
+#categories {
+ margin: 40px 0 0; width: 160px; float: left; position: relative; z-index: 1;
+ ul {
+ margin: 0; padding: 10px 0 0;
+ li {
+ list-style: none; margin: 0; padding: 0; font-size: 14px;
+ a { color: @grey; display: block; padding: 5px 10px 5px 15px; text-decoration: none; .border_radius_left(3); }
+ a:hover { color: @black; background: @light_grey * 0.15 + @white * 0.85; }
+ }
+ .all a { font-weight: bold; }
+ .current a {
+ background: @white; color: @black; border: 1px solid (@light_grey * 0.25 + @white * 0.75); border-right: none; border-left: 5px solid @bg;
+ padding-left: 10px;
+ }
+ }
+}
+
+/* Ads > Show */
+#ad {
+ div.header {
+ overflow: hidden;
+ h3 { font-size: 16px; margin: 0 0 3px; }
+ small {
+ a.category { font-weight: bold; color: @accent_colour; }
+ span.networks img { position: relative; top: 3px; }
+ }
+ span.brand {
+ float: right; color: @white;
+ a.brand_name { font-weight: bold; color: @accent_colour; }
+ }
+ }
+ div.content {
+ padding: 0; position: relative;
+ a.toggle_size {
+ display: block; .border_radius(3); background-color: @black; padding: 0 5px 0 26px;
+ background-position: 5px center; background-repeat: no-repeat; text-decoration: none; margin: 5px 5px 0 0;
+ position: absolute; top: 0; right: 0; line-height: 25px; z-index: 45;
+ }
+ img.creative { margin: 0 auto; max-width: 540px; display: block; }
+ object { position: relative; z-index: 44; }
+ object.video { line-height: 0; font-size: 0; }
+ object embed { position: relative; z-index: 45; line-height: 0; font-size: 0; }
+ }
+ div.content.not_video {
+ padding: 40px; text-align: center;
+ * { margin-left: auto; margin-right: auto; }
+ object.flash { margin-bottom: 0; }
+ }
+ div.footer {
+ padding: 0;
+ div.vote_views {
+ padding: 5px 10px; overflow: hidden;
+ div.share { float: right; margin: 2px 0 0 0; }
+ #login_register_msg, #encourage_vote_msg { line-height: 22px; font-weight: bold; color: @black; }
+ }
+ }
+}
+#sidebar {
+ #meta {
+ table {
+ margin: 0;
+ tr:last-child td { padding-bottom: 0; }
+ td {
+ padding: 0 0 5px;
+ ul.networks {
+ margin: 0; padding: 0;
+ li {
+ list-style: none; display: inline;
+ }
+ li {
+ }
+ }
+ }
+ td.label { color: @grey; white-space: nowrap; width: 1%; text-align: right; padding-right: 5px; }
+ }
+ }
+}
+
+/* Voting */
+div.voted {
+ font-size: 12px; line-height: 22px; color: @black; display: inline-block; font-weight: bold;
+ img { float: left; margin-right: 5px; padding: 3px; .border_radius(3); }
+}
+#voted_up {
+ img { background: @colour_positive * 0.66 + @bg * 0.15; }
+}
+#voted_down {
+ img { background: @colour_negative * 0.66 + @bg * 0.15; }
+}
+#encourage_comment {
+ display: inline-block; line-height: 22px; font-weight: bold;
+}
+#vote {
+ overflow: hidden; font-size: 12px; line-height: 22px; color: @black; float: left;
+ a {
+ color: @white; font-weight: bold; overflow: hidden; display: block;
+ width: 16px; text-decoration: none; text-align: center; font-size: 10px; padding: 3px; text-transform: uppercase;
+ }
+ a.up {
+ float: left; background: @colour_positive * 0.66 + @bg * 0.15; .border_radius_left(3);
+ :hover { background: @colour_positive * 0.85 + @bg * 0.15; }
+ }
+ a.down {
+ float: left; background: @colour_negative * 0.66 + @bg * 0.15; .border_radius_right(3);
+ margin: 0 5px 0 1px;
+ :hover { background: @colour_negative * 0.85 + @bg * 0.15; }
+ }
+}
+#vote.disabled {
+ a.up {
+ background: (@colour_positive * 0.66 + @bg * 0.15) * 0.15 + @grey * 0.85;
+ :hover { background: (@colour_positive * 0.85 + @bg * 0.15) * 0.25 + @grey * 0.75; }
+ }
+ a.down {
+ background: (@colour_negative * 0.66 + @bg * 0.15) * 0.15 + @grey * 0.85;
+ :hover { background: (@colour_negative * 0.85 + @bg * 0.15) * 0.25 + @grey * 0.75; }
+ }
+}
+#sidebar {
+ #ads > ul li, #recommendations > ul li {
+ width: 81px;
+ div.thumbnail {
+ a.thumbnail { height: 60px; width: 81px; }
+ }
+ div.text {
+ a.title { font-size: 11px; height: 14px; line-height: 14px; }
+ small { display: none; }
+ }
+ }
+ #brands > ul li {
+ width: 55px;
+ div.thumbnail {
+ a.thumbnail {
+ height: 45px; width: 45px;
+ img { max-height: 45px; max-width: 45px; }
+ }
+ }
+ div.text { display: none; }
+ }
+}
+
+/* My Account */
+#accounts_controller {
+ #top {
+ #page_title {
+ #page_options {
+ a.button.public_profile {
+ float: right; font-size: 16px; line-height: 1; height: auto; padding: 8px 35px 8px 15px; position: relative;
+ b.arrow { display: block; height: 0; width: 0; position: absolute; top: 10px; right: 15px; border: 6px solid transparent; border-right: none; border-left: 6px solid @white; margin: 0; }
+ }
+ a.button.goto_dashboard {
+ float: right; font-size: 16px; line-height: 1; height: auto; padding: 8px 15px 8px 35px; margin-right: 5px; position: relative;
+ b.arrow { display: block; height: 0; width: 0; position: absolute; top: 10px; left: 15px; border: 6px solid transparent; border-left: none; border-right: 6px solid @white; margin: 0; }
+ }
+ }
+ }
+ }
+ #account_nav {
+ float: left; width: 200px; margin: 0 20px 0 0;
+ ul.nav {
+ margin: 0; padding: 0;
+ li {
+ margin: 0 0 5px; display: block; list-style: none; padding: 0;
+ a {
+ display: block; height: 30px; text-decoration: none; color: @white;
+ b {
+ border: 15px solid transparent; border-right: none; border-left: 10px solid transparent; width: 0;
+ height: 0; float: right; display: none;
+ }
+ span {
+ .border_radius(3); background: @bg; display: block;
+ line-height: 30px; padding: 0 10px; font-size: 14px; font-weight: bold; margin: 0 10px 0 0;
+ }
+ }
+ :hover {
+ a {
+ color: @white;
+ b { border-left-color: @bg; display: block; }
+ span { background: @bg; .border_radius_right(0); }
+ }
+ }
+ }
+ li.current a {
+ b { border-left-color: @accent_colour; display: block; }
+ span { background: @accent_colour; color: @white; .border_radius_right(0); }
+ }
+ }
+ }
+ #main {
+ > div {
+ margin: 0 0 20px;
+ form { margin: 0; }
+ }
+ #profile {
+ a.avatar {
+ float: left; display: block;
+ width: 70px; overflow: hidden; position: relative; text-decoration: none;
+ img { width: 100%; }
+ span {
+ display: block; line-height: 1; padding: 3px; margin: 5px 0 0; color: @white; background: @accent_colour;
+ .border_radius(3); .text_shadow(1, 1, 0, @grey);
+ text-align: center; font-size: 10px; font-weight: bold; text-transform: uppercase;
+ }
+ }
+ form {
+ margin: 0 0 0 90px;
+ h4 { margin: 10px 0 20px; border-bottom: 1px solid (@light_grey * 0.5 + @white * 0.5); padding: 0; color: @bg; font-size: 16px; }
+ ul.choices {
+ li { width: 30%; }
+ }
+ div.extra { margin-top: 20px; }
+ }
+ }
+
+ #networks {
+ ul { margin: 0 -10px -10px 0; padding: 0; overflow: hidden;
+ li:hover
+ {
+ background: @light_grey; display: block; float: left; width: 180px;
+ padding: 10px; margin: 0 10px 10px 0; list-style: none; .border_radius(3);
+ position: relative;
+ * { line-height: normal; }
+ img { vertical-align: middle; float: left; }
+ .name { font-weight: bold; font-size: 14px; display: block; margin: -2px 0 0 42px; }
+ small {
+ font-size: 12px; color: @grey; display: block; margin-left: 42px;
+ strong { color: @black; font-weight: normal; }
+ }
+ :hover {
+ }
+ }
+ li.installed {
+ background: @white;
+ border: 2px solid @accent_colour; padding: 8px;
+ }
+ li.unavailable {
+ .name { color: @black; }
+ :hover {
+ background: @light_grey;
+ }
+ }
+ li:hover {
+ background: @light_grey * 0.5 + @white * 0.5;
+ }
+ }
+ }
+ }
+}
+
+/* Shopping Style Panel */
+#shopping_style {
+ div.header a.button.small { float: right; }
+ div.content {
+ p {
+ margin: 0 0 10px;
+ label { text-transform: uppercase; font-size: 11px; display: block; color: @bg; font-weight: bold; }
+ span { color: @black; }
+ span.toggle { white-space: nowrap; color: @grey; }
+ :last-child { margin: 0; }
+ }
+ p.more { text-align: left; font-weight: normal; }
+ p.less { display: none; margin: 0; }
+ }
+}
+
+/* People Controller */
+#people_controller.index {
+ #main {
+ div.panel {
+ float: left; width: 300px; margin: 0 20px 0 0;
+ :last-child { margin-right: 0; }
+ }
+ }
+}
+#people_controller.show {
+ #person_overview, #shopping_style {
+ a.button.small {
+ }
+ }
+ #content {
+ #shopping_style {
+ float: left; width: 240px; margin: 0 20px 0 0;
+ }
+ #main { width: 360px; }
+ }
+}
+
+/* Search Results */
+#search_results {
+ margin: 0 0 20px;
+ li {
+ :hover {
+ small { color: @white * 0.75 + @accent_colour * 0.25; }
+ }
+ }
+}
+#search {
+ div.content {
+ padding: 20px;
+ form {
+ margin: 0; float: none;
+ span.submit_and_options {
+ display: block;
+ }
+ }
+ p { margin: 0 0 15px; }
+ h4 { font-weight: normal; margin: 0 0 5px; }
+ }
+}
+
+/* Recommendations */
+#recommendations {
+ div.browse {
+ margin: 0; padding: 0; background: none;
+ ul { min-height: 0; .border_radius(0); }
+ }
+}
+
+/* Blank States */
+div.blank {
+ padding: 20px; background: @bg * 0.05 + @blue * 0.05 + @white * 0.9; position: relative;
+ border: 1px solid (@bg * 0.1 + @blue * 0.1 + @white * 0.8); z-index: 1;
+ h4 { font-size: 18px; margin: 0 0 10px; }
+ h4:last-child { margin: 0; }
+ p { font-size: 16px; margin: 0 0 10px; }
+ p:last-child { margin: 0; }
+ p.with_list_number.large {
+ span { margin-left: 48px; display: block; color: @white; }
+ }
+ p.earn span { font-size: 22px; color: @white; line-height: 48px; font-weight: bold; }
+ a { white-space: nowrap; }
+ a.hide {
+ position: absolute; top: -5px; right: -5px; display: block; height: 16px; width: 16px; padding: 3px; background: #E7E9F6; .border_radius(99);
+ }
+}
+
+div.blank.small {
+ padding: 10px 20px;
+ h4 { font-weight: normal; font-size: 16px; }
+ p { margin: 0; }
+}
+div.blank.tiny {
+ padding: 10px 20px;
+ h4 { font-weight: normal; font-size: 14px; }
+ p { margin: 0; font-size: 12px; }
+}
+div.blank.rounded {
+ .border_radius(3); margin: 0 0 20px;
+}
+div.blank.rounded.bottom { .border_radius_top(0); }
+div.blank.with_border_bottom { border-bottom: 1px solid (@bg * 0.1 + @blue * 0.1 + @white * 0.8); }
+div.blank.no_border_top { border-top: none; }
+div.blank.no_border_bottom { border-bottom: none; }
+div.blank.no_side_borders { border-right: none; border-left: none; }
+div.panel {
+ div.blank {
+ padding: 10px 20px; overflow: hidden; margin: 0;
+ h4 { font-weight: normal; font-size: 14px; }
+ p, ul { margin: 0 0 10px; font-size: 12px; }
+ p:last-child, ul:last-child { margin: 0; }
+ }
+}
+
+#yelow {
+ #short {
+ color: #fea;
+ }
+ #long {
+ color: #ffeeaa;
+ }
+ #rgba {
+ color: rgba(255, 238, 170, 0.1);
+ }
+}
+
+#blue {
+ #short {
+ color: #00f;
+ }
+ #long {
+ color: #0000ff;
+ }
+ #rgba {
+ color: rgba(0, 0, 255, 0.1);
+ }
+}
+
+#overflow {
+ .a { color: #111111 - #444444; } // #000000
+ .b { color: #eee + #fff; } // #ffffff
+ .c { color: #aaa * 3; } // #ffffff
+ .d { color: #00ee00 + #009900; } // #00ff00
+}
+
+#grey {
+ color: rgb(200, 200, 200);
+}
+
+#808080 {
+ color: hsl(50, 0%, 50%);
+}
+
+#00ff00 {
+ color: hsl(120, 100%, 50%);
+}
+/******************\
+* *
+* Comment Header *
+* *
+\******************/
+
+/*
+
+ Comment
+
+*/
+
+/*
+ * Comment Test
+ *
+ * - cloudhead (http://cloudhead.net)
+ *
+ */
+
+////////////////
+@var: "content";
+////////////////
+
+/* Colors
+ * ------
+ * #EDF8FC (background blue)
+ * #166C89 (darkest blue)
+ *
+ * Text:
+ * #333 (standard text) // A comment within a comment!
+ * #1F9EC9 (standard link)
+ *
+ */
+
+/* @group Variables
+------------------- */
+#comments /* boo */ {
+ /**/ // An empty comment
+ color: red; /* A C-style comment */
+ background-color: orange; // A little comment
+ font-size: 12px;
+
+ /* lost comment */ content: @var;
+
+ border: 1px solid black;
+
+ // padding & margin //
+ padding: 0;
+ margin: 2em;
+} //
+
+/* commented out
+ #more-comments {
+ color: grey;
+ }
+*/
+
+#last { color: blue }
+//
+.comma-delimited {
+ background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+ text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
+ -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset,
+ 0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
+}
+@font-face {
+ font-family: Headline;
+ src: local(Futura-Medium),
+ url(fonts.svg#MyGeometricModern) format("svg");
+}
+.other {
+ -moz-transform: translate(0, 11em) rotate(-90deg);
+}
+p:not([class*="lead"]) {
+ color: black;
+}
+
+input[type="text"].class#id[attr=32]:not(1) {
+ color: white;
+}
+
+div#id.class[a=1][b=2].class:not(1) {
+ color: white;
+}
+
+ul.comma > li:not(:only-child)::after {
+ color: white;
+}
+
+ol.comma > li:nth-last-child(2)::after {
+ color: white;
+}
+
+li:nth-child(4n+1),
+li:nth-child(-5n),
+li:nth-child(-n+2) {
+ color: white;
+}
+
+a[href^="http://"] {
+ color: black;
+}
+
+a[href$="http://"] {
+ color: black;
+}
+
+form[data-disabled] {
+ color: black;
+}
+
+p::before {
+ color: black;
+}
+@charset "utf-8";
+div { color: black; }
+div { width: 99%; }
+
+* {
+ min-width: 45em;
+}
+
+h1, h2 > a > p, h3 {
+ color: none;
+}
+
+div.class {
+ color: blue;
+}
+
+div#id {
+ color: green;
+}
+
+.class#id {
+ color: purple;
+}
+
+.one.two.three {
+ color: grey;
+}
+
+@media print {
+ font-size: 3em;
+}
+
+@media screen {
+ font-size: 10px;
+}
+
+@font-face {
+ font-family: 'Garamond Pro';
+ src: url("/fonts/garamond-pro.ttf");
+}
+
+a:hover, a:link {
+ color: #999;
+}
+
+p, p:first-child {
+ text-transform: none;
+}
+
+q:lang(no) {
+ quotes: none;
+}
+
+p + h1 {
+ font-size: 2.2em;
+}
+
+#shorthands {
+ border: 1px solid #000;
+ font: 12px/16px Arial;
+ margin: 1px 0;
+ padding: 0 auto;
+ background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+
+#more-shorthands {
+ margin: 0;
+ padding: 1px 0 2px 0;
+ font: normal small/20px 'Trebuchet MS', Verdana, sans-serif;
+}
+
+.misc {
+ -moz-border-radius: 2px;
+ display: -moz-inline-stack;
+ width: .1em;
+ background-color: #009998;
+ background-image: url(images/image.jpg);
+ background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
+ margin: ;
+}
+
+#important {
+ color: red !important;
+ width: 100%!important;
+ height: 20px ! important;
+}
+
+#functions {
+ @var: 10;
+ color: color("evil red"); // #660000
+ width: increment(15);
+ height: undefined("self");
+ border-width: add(2, 3);
+ variable: increment(@var);
+}
+
+#built-in {
+ @r: 32;
+ escaped: e("-Some::weird(#thing, y)");
+ lighten: lighten(#ff0000, 50%);
+ darken: darken(#ff0000, 50%);
+ saturate: saturate(#29332f, 20%);
+ desaturate: desaturate(#203c31, 20%);
+ greyscale: greyscale(#203c31);
+ format: %("rgb(%d, %d, %d)", @r, 128, 64);
+ format-string: %("hello %s", "world");
+ eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64));
+}
+
+@var: @a;
+@a: 100%;
+
+.lazy-eval {
+ width: @var;
+}
+.mixin (@a: 1px, @b: 50%) {
+ width: @a * 5;
+ height: @b - 1%;
+}
+
+.mixina (@style, @width, @color: black) {
+ border: @width @style @color;
+}
+
+.mixiny
+(@a: 0, @b: 0) {
+ margin: @a;
+ padding: @b;
+}
+
+.hidden() {
+ color: transparent;
+}
+
+.two-args {
+ color: blue;
+ .mixin(2px, 100%);
+ .mixina(dotted, 2px);
+}
+
+.one-arg {
+ .mixin(3px);
+}
+
+.no-parens {
+ .mixin;
+}
+
+.no-args {
+ .mixin();
+}
+
+.var-args {
+ @var: 9;
+ .mixin(@var, @var * 2);
+}
+
+.multi-mix {
+ .mixin(2px, 30%);
+ .mixiny(4, 5);
+}
+
+.maxa(@arg1: 10, @arg2: #f00) {
+ padding: @arg1 * 2px;
+ color: @arg2;
+}
+
+body {
+ .maxa(15);
+}
+
+@glob: 5;
+.global-mixin(@a:2) {
+ width: @glob + @a;
+}
+
+.scope-mix {
+ .global-mixin(3);
+}
+
+.nested-ruleset (@width: 200px) {
+ width: @width;
+ .column { margin: @width; }
+}
+.content {
+ .nested-ruleset(600px);
+}
+
+//
+
+.same-var-name2(@radius) {
+ radius: @radius;
+}
+.same-var-name(@radius) {
+ .same-var-name2(@radius);
+}
+#same-var-name {
+ .same-var-name(5px);
+}
+
+//
+
+.var-inside () {
+ @var: 10px;
+ width: @var;
+}
+#var-inside { .var-inside; }
+.mix-inner (@var) {
+ border-width: @var;
+}
+
+.mix (@a: 10) {
+ .inner {
+ height: @a * 10;
+
+ .innest {
+ width: @a;
+ .mix-inner(@a * 2);
+ }
+ }
+}
+
+.class {
+ .mix(30);
+}
+.mixin () {
+ zero: 0;
+}
+.mixin (@a: 1px) {
+ one: 1;
+}
+.mixin (@a) {
+ one-req: 1;
+}
+.mixin (@a: 1px, @b: 2px) {
+ two: 2;
+}
+
+.mixin (@a, @b, @c) {
+ three-req: 3;
+}
+
+.mixin (@a: 1px, @b: 2px, @c: 3px) {
+ three: 3;
+}
+
+.zero {
+ .mixin();
+}
+
+.one {
+ .mixin(1);
+}
+
+.two {
+ .mixin(1, 2);
+}
+
+.three {
+ .mixin(1, 2, 3);
+}
+
+//
+
+.mixout ('left') {
+ left: 1;
+}
+
+.mixout ('right') {
+ right: 1;
+}
+
+.left {
+ .mixout('left');
+}
+.right {
+ .mixout('right');
+}
+
+//
+
+.border (@side, @width) {
+ color: black;
+ .border-side(@side, @width);
+}
+.border-side (left, @w) {
+ border-left: @w;
+}
+.border-side (right, @w) {
+ border-right: @w;
+}
+
+.border-right {
+ .border(right, 4px);
+}
+.border-left {
+ .border(left, 4px);
+}
+
+//
+
+
+.border-radius (@r) {
+ both: @r * 10;
+}
+.border-radius (@r, left) {
+ left: @r;
+}
+.border-radius (@r, right) {
+ right: @r;
+}
+
+.only-right {
+ .border-radius(33, right);
+}
+.only-left {
+ .border-radius(33, left);
+}
+.left-right {
+ .border-radius(33);
+}
+.mixin { border: 1px solid black; }
+.mixout { border-color: orange; }
+.borders { border-style: dashed; }
+
+#namespace {
+ .borders {
+ border-style: dotted;
+ }
+ .biohazard {
+ content: "death";
+ .man {
+ color: transparent;
+ }
+ }
+}
+#theme {
+ > .mixin {
+ background-color: grey;
+ }
+}
+#container {
+ color: black;
+ .mixin;
+ .mixout;
+ #theme > .mixin;
+}
+
+#header {
+ .milk {
+ color: white;
+ .mixin;
+ #theme > .mixin;
+ }
+ #cookie {
+ .chips {
+ #namespace .borders;
+ .calories {
+ #container;
+ }
+ }
+ .borders;
+ }
+}
+.secure-zone { #namespace .biohazard .man; }
+.direct {
+ #namespace > .borders;
+}
+#operations {
+ color: #110000 + #000011 + #001100; // #111111
+ height: 10px / 2px + 6px - 1px * 2; // 9px
+ width: 2 * 4 - 5em; // 3em
+ .spacing {
+ height: 10px / 2px+6px-1px*2;
+ width: 2 * 4-5em;
+ }
+ substraction: 20 - 10 - 5 - 5; // 0
+ division: 20 / 5 / 4; // 1
+}
+
+@x: 4;
+@y: 12em;
+
+.with-variables {
+ height: @x + @y; // 16em
+ width: 12 + @y; // 24em
+ size: 5cm - @x; // 1cm
+}
+
+@z: -2;
+
+.negative {
+ height: 2px + @z; // 0px
+ width: 2px - @z; // 4px
+}
+
+.shorthands {
+ padding: -1px 2px 0 -4px; //
+}
+
+.colors {
+ color: #123; // #112233
+ border-color: #234 + #111111; // #334455
+ background-color: #222222 - #fff; // #000000
+ .other {
+ color: 2 * #111; // #222222
+ border-color: #333333 / 3 + #111; // #222222
+ }
+}
+.parens {
+ @var: 1px;
+ border: (@var * 2) solid black;
+ margin: (@var * 1) (@var + 2) (4 * 4) 3;
+ width: (6 * 6);
+ padding: 2px (6px * 6px);
+}
+
+.more-parens {
+ @var: (2 * 2);
+ padding: (2 * @var) 4 4 (@var * 1px);
+ width: (@var * @var) * 6;
+ height: (7 * 7) + (8 * 8);
+ margin: 4 * (5 + 5) / 2 - (@var * 2);
+ //margin: (6 * 6)px;
+}
+
+.nested-parens {
+ width: 2 * (4 * (2 + (1 + 6))) - 1;
+ height: ((2+3)*(2+3) / (9-4)) + 1;
+}
+
+.mixed-units {
+ margin: 2px 4em 1 5pc;
+ padding: (2px + 4px) 1em 2px 2;
+}
+#first > .one {
+ > #second .two > #deux {
+ width: 50%;
+ #third {
+ &:focus {
+ color: black;
+ #fifth {
+ > #sixth {
+ .seventh #eighth {
+ + #ninth {
+ color: purple;
+ }
+ }
+ }
+ }
+ }
+ height: 100%;
+ }
+ #fourth, #five, #six {
+ color: #110000;
+ .seven, .eight > #nine {
+ border: 1px solid black;
+ }
+ #ten {
+ color: red;
+ }
+ }
+ }
+ font-size: 2em;
+}
+@x: blue;
+@z: transparent;
+@mix: none;
+
+.mixin {
+ @mix: #989;
+}
+
+.tiny-scope {
+ color: @mix; // #989
+ .mixin;
+}
+
+.scope1 {
+ @y: orange;
+ @z: black;
+ color: @x; // blue
+ border-color: @z; // black
+ .hidden {
+ @x: #131313;
+ }
+ .scope2 {
+ @y: red;
+ color: @x; // blue
+ .scope3 {
+ @local: white;
+ color: @y; // red
+ border-color: @z; // black
+ background-color: @local; // white
+ }
+ }
+}h1, h2, h3 {
+ a, p {
+ &:hover {
+ color: red;
+ }
+ }
+}
+
+#all { color: blue; }
+#the { color: blue; }
+#same { color: blue; }
+
+ul, li, div, q, blockquote, textarea {
+ margin: 0;
+}
+
+td {
+ margin: 0;
+ padding: 0;
+}
+
+td, input {
+ line-height: 1em;
+}
+#strings {
+ background-image: url("http://son-of-a-banana.com");
+ quotes: "~" "~";
+ content: "#*%:&^,)!.(~*})";
+ empty: "";
+ brackets: "{" "}";
+}
+#comments {
+ content: "/* hello */ // not-so-secret";
+}
+#single-quote {
+ quotes: "'" "'";
+ content: '""#!&""';
+ empty: '';
+}
+@a: 2;
+@x: @a * @a;
+@y: @x + 1;
+@z: @x * 2 + @y;
+
+.variables {
+ width: @z + 1cm; // 14cm
+}
+
+@b: @a * 10;
+@c: #888;
+
+@fonts: "Trebuchet MS", Verdana, sans-serif;
+@f: @fonts;
+
+@quotes: "~" "~";
+@q: @quotes;
+
+.variables {
+ height: @b + @x + 0px; // 24px
+ color: @c;
+ font-family: @f;
+ quotes: @q;
+}
+
+.redefinition {
+ @var: 4;
+ @var: 2;
+ @var: 3;
+ three: @var;
+}
+
+.values {
+ @a: 'Trebuchet';
+ font-family: @a, @a, @a;
+}
+
+
+.whitespace
+ { color: white; }
+
+.whitespace
+{
+ color: white;
+}
+ .whitespace
+{ color: white; }
+
+.whitespace{color:white;}
+.whitespace { color : white ; }
+
+.white,
+.space,
+.mania
+{ color: white; }
+
+.no-semi-column { color: white }
+.no-semi-column {
+ color: white;
+ white-space: pre
+}
+.no-semi-column {border: 2px solid white}
+.newlines {
+ background: the,
+ great,
+ wall;
+ border: 2px
+ solid
+ black;
+}
+.empty {
+
+}
+#yelow {
+ #short {
+ color: #fea;
+ }
+ #long {
+ color: #ffeeaa;
+ }
+ #rgba {
+ color: rgba(255, 238, 170, 0.1);
+ }
+}
+
+#blue {
+ #short {
+ color: #00f;
+ }
+ #long {
+ color: #0000ff;
+ }
+ #rgba {
+ color: rgba(0, 0, 255, 0.1);
+ }
+}
+
+#overflow {
+ .a { color: #111111 - #444444; } // #000000
+ .b { color: #eee + #fff; } // #ffffff
+ .c { color: #aaa * 3; } // #ffffff
+ .d { color: #00ee00 + #009900; } // #00ff00
+}
+
+#grey {
+ color: rgb(200, 200, 200);
+}
+
+#808080 {
+ color: hsl(50, 0%, 50%);
+}
+
+#00ff00 {
+ color: hsl(120, 100%, 50%);
+}
+/******************\
+* *
+* Comment Header *
+* *
+\******************/
+
+/*
+
+ Comment
+
+*/
+
+/*
+ * Comment Test
+ *
+ * - cloudhead (http://cloudhead.net)
+ *
+ */
+
+////////////////
+@var: "content";
+////////////////
+
+/* Colors
+ * ------
+ * #EDF8FC (background blue)
+ * #166C89 (darkest blue)
+ *
+ * Text:
+ * #333 (standard text) // A comment within a comment!
+ * #1F9EC9 (standard link)
+ *
+ */
+
+/* @group Variables
+------------------- */
+#comments /* boo */ {
+ /**/ // An empty comment
+ color: red; /* A C-style comment */
+ background-color: orange; // A little comment
+ font-size: 12px;
+
+ /* lost comment */ content: @var;
+
+ border: 1px solid black;
+
+ // padding & margin //
+ padding: 0;
+ margin: 2em;
+} //
+
+/* commented out
+ #more-comments {
+ color: grey;
+ }
+*/
+
+#last { color: blue }
+//
+.comma-delimited {
+ background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+ text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
+ -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset,
+ 0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
+}
+@font-face {
+ font-family: Headline;
+ src: local(Futura-Medium),
+ url(fonts.svg#MyGeometricModern) format("svg");
+}
+.other {
+ -moz-transform: translate(0, 11em) rotate(-90deg);
+}
+p:not([class*="lead"]) {
+ color: black;
+}
+
+input[type="text"].class#id[attr=32]:not(1) {
+ color: white;
+}
+
+div#id.class[a=1][b=2].class:not(1) {
+ color: white;
+}
+
+ul.comma > li:not(:only-child)::after {
+ color: white;
+}
+
+ol.comma > li:nth-last-child(2)::after {
+ color: white;
+}
+
+li:nth-child(4n+1),
+li:nth-child(-5n),
+li:nth-child(-n+2) {
+ color: white;
+}
+
+a[href^="http://"] {
+ color: black;
+}
+
+a[href$="http://"] {
+ color: black;
+}
+
+form[data-disabled] {
+ color: black;
+}
+
+p::before {
+ color: black;
+}
+@charset "utf-8";
+div { color: black; }
+div { width: 99%; }
+
+* {
+ min-width: 45em;
+}
+
+h1, h2 > a > p, h3 {
+ color: none;
+}
+
+div.class {
+ color: blue;
+}
+
+div#id {
+ color: green;
+}
+
+.class#id {
+ color: purple;
+}
+
+.one.two.three {
+ color: grey;
+}
+
+@media print {
+ font-size: 3em;
+}
+
+@media screen {
+ font-size: 10px;
+}
+
+@font-face {
+ font-family: 'Garamond Pro';
+ src: url("/fonts/garamond-pro.ttf");
+}
+
+a:hover, a:link {
+ color: #999;
+}
+
+p, p:first-child {
+ text-transform: none;
+}
+
+q:lang(no) {
+ quotes: none;
+}
+
+p + h1 {
+ font-size: 2.2em;
+}
+
+#shorthands {
+ border: 1px solid #000;
+ font: 12px/16px Arial;
+ margin: 1px 0;
+ padding: 0 auto;
+ background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+
+#more-shorthands {
+ margin: 0;
+ padding: 1px 0 2px 0;
+ font: normal small/20px 'Trebuchet MS', Verdana, sans-serif;
+}
+
+.misc {
+ -moz-border-radius: 2px;
+ display: -moz-inline-stack;
+ width: .1em;
+ background-color: #009998;
+ background-image: url(images/image.jpg);
+ background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
+ margin: ;
+}
+
+#important {
+ color: red !important;
+ width: 100%!important;
+ height: 20px ! important;
+}
+
+#functions {
+ @var: 10;
+ color: color("evil red"); // #660000
+ width: increment(15);
+ height: undefined("self");
+ border-width: add(2, 3);
+ variable: increment(@var);
+}
+
+#built-in {
+ @r: 32;
+ escaped: e("-Some::weird(#thing, y)");
+ lighten: lighten(#ff0000, 50%);
+ darken: darken(#ff0000, 50%);
+ saturate: saturate(#29332f, 20%);
+ desaturate: desaturate(#203c31, 20%);
+ greyscale: greyscale(#203c31);
+ format: %("rgb(%d, %d, %d)", @r, 128, 64);
+ format-string: %("hello %s", "world");
+ eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64));
+}
+
+@var: @a;
+@a: 100%;
+
+.lazy-eval {
+ width: @var;
+}
+.mixin (@a: 1px, @b: 50%) {
+ width: @a * 5;
+ height: @b - 1%;
+}
+
+.mixina (@style, @width, @color: black) {
+ border: @width @style @color;
+}
+
+.mixiny
+(@a: 0, @b: 0) {
+ margin: @a;
+ padding: @b;
+}
+
+.hidden() {
+ color: transparent;
+}
+
+.two-args {
+ color: blue;
+ .mixin(2px, 100%);
+ .mixina(dotted, 2px);
+}
+
+.one-arg {
+ .mixin(3px);
+}
+
+.no-parens {
+ .mixin;
+}
+
+.no-args {
+ .mixin();
+}
+
+.var-args {
+ @var: 9;
+ .mixin(@var, @var * 2);
+}
+
+.multi-mix {
+ .mixin(2px, 30%);
+ .mixiny(4, 5);
+}
+
+.maxa(@arg1: 10, @arg2: #f00) {
+ padding: @arg1 * 2px;
+ color: @arg2;
+}
+
+body {
+ .maxa(15);
+}
+
+@glob: 5;
+.global-mixin(@a:2) {
+ width: @glob + @a;
+}
+
+.scope-mix {
+ .global-mixin(3);
+}
+
+.nested-ruleset (@width: 200px) {
+ width: @width;
+ .column { margin: @width; }
+}
+.content {
+ .nested-ruleset(600px);
+}
+
+//
+
+.same-var-name2(@radius) {
+ radius: @radius;
+}
+.same-var-name(@radius) {
+ .same-var-name2(@radius);
+}
+#same-var-name {
+ .same-var-name(5px);
+}
+
+//
+
+.var-inside () {
+ @var: 10px;
+ width: @var;
+}
+#var-inside { .var-inside; }
+.mix-inner (@var) {
+ border-width: @var;
+}
+
+.mix (@a: 10) {
+ .inner {
+ height: @a * 10;
+
+ .innest {
+ width: @a;
+ .mix-inner(@a * 2);
+ }
+ }
+}
+
+.class {
+ .mix(30);
+}
+.mixin () {
+ zero: 0;
+}
+.mixin (@a: 1px) {
+ one: 1;
+}
+.mixin (@a) {
+ one-req: 1;
+}
+.mixin (@a: 1px, @b: 2px) {
+ two: 2;
+}
+
+.mixin (@a, @b, @c) {
+ three-req: 3;
+}
+
+.mixin (@a: 1px, @b: 2px, @c: 3px) {
+ three: 3;
+}
+
+.zero {
+ .mixin();
+}
+
+.one {
+ .mixin(1);
+}
+
+.two {
+ .mixin(1, 2);
+}
+
+.three {
+ .mixin(1, 2, 3);
+}
+
+//
+
+.mixout ('left') {
+ left: 1;
+}
+
+.mixout ('right') {
+ right: 1;
+}
+
+.left {
+ .mixout('left');
+}
+.right {
+ .mixout('right');
+}
+
+//
+
+.border (@side, @width) {
+ color: black;
+ .border-side(@side, @width);
+}
+.border-side (left, @w) {
+ border-left: @w;
+}
+.border-side (right, @w) {
+ border-right: @w;
+}
+
+.border-right {
+ .border(right, 4px);
+}
+.border-left {
+ .border(left, 4px);
+}
+
+//
+
+
+.border-radius (@r) {
+ both: @r * 10;
+}
+.border-radius (@r, left) {
+ left: @r;
+}
+.border-radius (@r, right) {
+ right: @r;
+}
+
+.only-right {
+ .border-radius(33, right);
+}
+.only-left {
+ .border-radius(33, left);
+}
+.left-right {
+ .border-radius(33);
+}
+.mixin { border: 1px solid black; }
+.mixout { border-color: orange; }
+.borders { border-style: dashed; }
+
+#namespace {
+ .borders {
+ border-style: dotted;
+ }
+ .biohazard {
+ content: "death";
+ .man {
+ color: transparent;
+ }
+ }
+}
+#theme {
+ > .mixin {
+ background-color: grey;
+ }
+}
+#container {
+ color: black;
+ .mixin;
+ .mixout;
+ #theme > .mixin;
+}
+
+#header {
+ .milk {
+ color: white;
+ .mixin;
+ #theme > .mixin;
+ }
+ #cookie {
+ .chips {
+ #namespace .borders;
+ .calories {
+ #container;
+ }
+ }
+ .borders;
+ }
+}
+.secure-zone { #namespace .biohazard .man; }
+.direct {
+ #namespace > .borders;
+}
+#operations {
+ color: #110000 + #000011 + #001100; // #111111
+ height: 10px / 2px + 6px - 1px * 2; // 9px
+ width: 2 * 4 - 5em; // 3em
+ .spacing {
+ height: 10px / 2px+6px-1px*2;
+ width: 2 * 4-5em;
+ }
+ substraction: 20 - 10 - 5 - 5; // 0
+ division: 20 / 5 / 4; // 1
+}
+
+@x: 4;
+@y: 12em;
+
+.with-variables {
+ height: @x + @y; // 16em
+ width: 12 + @y; // 24em
+ size: 5cm - @x; // 1cm
+}
+
+@z: -2;
+
+.negative {
+ height: 2px + @z; // 0px
+ width: 2px - @z; // 4px
+}
+
+.shorthands {
+ padding: -1px 2px 0 -4px; //
+}
+
+.colors {
+ color: #123; // #112233
+ border-color: #234 + #111111; // #334455
+ background-color: #222222 - #fff; // #000000
+ .other {
+ color: 2 * #111; // #222222
+ border-color: #333333 / 3 + #111; // #222222
+ }
+}
+.parens {
+ @var: 1px;
+ border: (@var * 2) solid black;
+ margin: (@var * 1) (@var + 2) (4 * 4) 3;
+ width: (6 * 6);
+ padding: 2px (6px * 6px);
+}
+
+.more-parens {
+ @var: (2 * 2);
+ padding: (2 * @var) 4 4 (@var * 1px);
+ width: (@var * @var) * 6;
+ height: (7 * 7) + (8 * 8);
+ margin: 4 * (5 + 5) / 2 - (@var * 2);
+ //margin: (6 * 6)px;
+}
+
+.nested-parens {
+ width: 2 * (4 * (2 + (1 + 6))) - 1;
+ height: ((2+3)*(2+3) / (9-4)) + 1;
+}
+
+.mixed-units {
+ margin: 2px 4em 1 5pc;
+ padding: (2px + 4px) 1em 2px 2;
+}
+#first > .one {
+ > #second .two > #deux {
+ width: 50%;
+ #third {
+ &:focus {
+ color: black;
+ #fifth {
+ > #sixth {
+ .seventh #eighth {
+ + #ninth {
+ color: purple;
+ }
+ }
+ }
+ }
+ }
+ height: 100%;
+ }
+ #fourth, #five, #six {
+ color: #110000;
+ .seven, .eight > #nine {
+ border: 1px solid black;
+ }
+ #ten {
+ color: red;
+ }
+ }
+ }
+ font-size: 2em;
+}
+@x: blue;
+@z: transparent;
+@mix: none;
+
+.mixin {
+ @mix: #989;
+}
+
+.tiny-scope {
+ color: @mix; // #989
+ .mixin;
+}
+
+.scope1 {
+ @y: orange;
+ @z: black;
+ color: @x; // blue
+ border-color: @z; // black
+ .hidden {
+ @x: #131313;
+ }
+ .scope2 {
+ @y: red;
+ color: @x; // blue
+ .scope3 {
+ @local: white;
+ color: @y; // red
+ border-color: @z; // black
+ background-color: @local; // white
+ }
+ }
+}h1, h2, h3 {
+ a, p {
+ &:hover {
+ color: red;
+ }
+ }
+}
+
+#all { color: blue; }
+#the { color: blue; }
+#same { color: blue; }
+
+ul, li, div, q, blockquote, textarea {
+ margin: 0;
+}
+
+td {
+ margin: 0;
+ padding: 0;
+}
+
+td, input {
+ line-height: 1em;
+}
+#strings {
+ background-image: url("http://son-of-a-banana.com");
+ quotes: "~" "~";
+ content: "#*%:&^,)!.(~*})";
+ empty: "";
+ brackets: "{" "}";
+}
+#comments {
+ content: "/* hello */ // not-so-secret";
+}
+#single-quote {
+ quotes: "'" "'";
+ content: '""#!&""';
+ empty: '';
+}
+@a: 2;
+@x: @a * @a;
+@y: @x + 1;
+@z: @x * 2 + @y;
+
+.variables {
+ width: @z + 1cm; // 14cm
+}
+
+@b: @a * 10;
+@c: #888;
+
+@fonts: "Trebuchet MS", Verdana, sans-serif;
+@f: @fonts;
+
+@quotes: "~" "~";
+@q: @quotes;
+
+.variables {
+ height: @b + @x + 0px; // 24px
+ color: @c;
+ font-family: @f;
+ quotes: @q;
+}
+
+.redefinition {
+ @var: 4;
+ @var: 2;
+ @var: 3;
+ three: @var;
+}
+
+.values {
+ @a: 'Trebuchet';
+ font-family: @a, @a, @a;
+}
+
+
+.whitespace
+ { color: white; }
+
+.whitespace
+{
+ color: white;
+}
+ .whitespace
+{ color: white; }
+
+.whitespace{color:white;}
+.whitespace { color : white ; }
+
+.white,
+.space,
+.mania
+{ color: white; }
+
+.no-semi-column { color: white }
+.no-semi-column {
+ color: white;
+ white-space: pre
+}
+.no-semi-column {border: 2px solid white}
+.newlines {
+ background: the,
+ great,
+ wall;
+ border: 2px
+ solid
+ black;
+}
+.empty {
+
+}
+#yelow {
+ #short {
+ color: #fea;
+ }
+ #long {
+ color: #ffeeaa;
+ }
+ #rgba {
+ color: rgba(255, 238, 170, 0.1);
+ }
+}
+
+#blue {
+ #short {
+ color: #00f;
+ }
+ #long {
+ color: #0000ff;
+ }
+ #rgba {
+ color: rgba(0, 0, 255, 0.1);
+ }
+}
+
+#overflow {
+ .a { color: #111111 - #444444; } // #000000
+ .b { color: #eee + #fff; } // #ffffff
+ .c { color: #aaa * 3; } // #ffffff
+ .d { color: #00ee00 + #009900; } // #00ff00
+}
+
+#grey {
+ color: rgb(200, 200, 200);
+}
+
+#808080 {
+ color: hsl(50, 0%, 50%);
+}
+
+#00ff00 {
+ color: hsl(120, 100%, 50%);
+}
+/******************\
+* *
+* Comment Header *
+* *
+\******************/
+
+/*
+
+ Comment
+
+*/
+
+/*
+ * Comment Test
+ *
+ * - cloudhead (http://cloudhead.net)
+ *
+ */
+
+////////////////
+@var: "content";
+////////////////
+
+/* Colors
+ * ------
+ * #EDF8FC (background blue)
+ * #166C89 (darkest blue)
+ *
+ * Text:
+ * #333 (standard text) // A comment within a comment!
+ * #1F9EC9 (standard link)
+ *
+ */
+
+/* @group Variables
+------------------- */
+#comments /* boo */ {
+ /**/ // An empty comment
+ color: red; /* A C-style comment */
+ background-color: orange; // A little comment
+ font-size: 12px;
+
+ /* lost comment */ content: @var;
+
+ border: 1px solid black;
+
+ // padding & margin //
+ padding: 0;
+ margin: 2em;
+} //
+
+/* commented out
+ #more-comments {
+ color: grey;
+ }
+*/
+
+#last { color: blue }
+//
+.comma-delimited {
+ background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+ text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
+ -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset,
+ 0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
+}
+@font-face {
+ font-family: Headline;
+ src: local(Futura-Medium),
+ url(fonts.svg#MyGeometricModern) format("svg");
+}
+.other {
+ -moz-transform: translate(0, 11em) rotate(-90deg);
+}
+p:not([class*="lead"]) {
+ color: black;
+}
+
+input[type="text"].class#id[attr=32]:not(1) {
+ color: white;
+}
+
+div#id.class[a=1][b=2].class:not(1) {
+ color: white;
+}
+
+ul.comma > li:not(:only-child)::after {
+ color: white;
+}
+
+ol.comma > li:nth-last-child(2)::after {
+ color: white;
+}
+
+li:nth-child(4n+1),
+li:nth-child(-5n),
+li:nth-child(-n+2) {
+ color: white;
+}
+
+a[href^="http://"] {
+ color: black;
+}
+
+a[href$="http://"] {
+ color: black;
+}
+
+form[data-disabled] {
+ color: black;
+}
+
+p::before {
+ color: black;
+}
+@charset "utf-8";
+div { color: black; }
+div { width: 99%; }
+
+* {
+ min-width: 45em;
+}
+
+h1, h2 > a > p, h3 {
+ color: none;
+}
+
+div.class {
+ color: blue;
+}
+
+div#id {
+ color: green;
+}
+
+.class#id {
+ color: purple;
+}
+
+.one.two.three {
+ color: grey;
+}
+
+@media print {
+ font-size: 3em;
+}
+
+@media screen {
+ font-size: 10px;
+}
+
+@font-face {
+ font-family: 'Garamond Pro';
+ src: url("/fonts/garamond-pro.ttf");
+}
+
+a:hover, a:link {
+ color: #999;
+}
+
+p, p:first-child {
+ text-transform: none;
+}
+
+q:lang(no) {
+ quotes: none;
+}
+
+p + h1 {
+ font-size: 2.2em;
+}
+
+#shorthands {
+ border: 1px solid #000;
+ font: 12px/16px Arial;
+ margin: 1px 0;
+ padding: 0 auto;
+ background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+
+#more-shorthands {
+ margin: 0;
+ padding: 1px 0 2px 0;
+ font: normal small/20px 'Trebuchet MS', Verdana, sans-serif;
+}
+
+.misc {
+ -moz-border-radius: 2px;
+ display: -moz-inline-stack;
+ width: .1em;
+ background-color: #009998;
+ background-image: url(images/image.jpg);
+ background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
+ margin: ;
+}
+
+#important {
+ color: red !important;
+ width: 100%!important;
+ height: 20px ! important;
+}
+
+#functions {
+ @var: 10;
+ color: color("evil red"); // #660000
+ width: increment(15);
+ height: undefined("self");
+ border-width: add(2, 3);
+ variable: increment(@var);
+}
+
+#built-in {
+ @r: 32;
+ escaped: e("-Some::weird(#thing, y)");
+ lighten: lighten(#ff0000, 50%);
+ darken: darken(#ff0000, 50%);
+ saturate: saturate(#29332f, 20%);
+ desaturate: desaturate(#203c31, 20%);
+ greyscale: greyscale(#203c31);
+ format: %("rgb(%d, %d, %d)", @r, 128, 64);
+ format-string: %("hello %s", "world");
+ eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64));
+}
+
+@var: @a;
+@a: 100%;
+
+.lazy-eval {
+ width: @var;
+}
+.mixin (@a: 1px, @b: 50%) {
+ width: @a * 5;
+ height: @b - 1%;
+}
+
+.mixina (@style, @width, @color: black) {
+ border: @width @style @color;
+}
+
+.mixiny
+(@a: 0, @b: 0) {
+ margin: @a;
+ padding: @b;
+}
+
+.hidden() {
+ color: transparent;
+}
+
+.two-args {
+ color: blue;
+ .mixin(2px, 100%);
+ .mixina(dotted, 2px);
+}
+
+.one-arg {
+ .mixin(3px);
+}
+
+.no-parens {
+ .mixin;
+}
+
+.no-args {
+ .mixin();
+}
+
+.var-args {
+ @var: 9;
+ .mixin(@var, @var * 2);
+}
+
+.multi-mix {
+ .mixin(2px, 30%);
+ .mixiny(4, 5);
+}
+
+.maxa(@arg1: 10, @arg2: #f00) {
+ padding: @arg1 * 2px;
+ color: @arg2;
+}
+
+body {
+ .maxa(15);
+}
+
+@glob: 5;
+.global-mixin(@a:2) {
+ width: @glob + @a;
+}
+
+.scope-mix {
+ .global-mixin(3);
+}
+
+.nested-ruleset (@width: 200px) {
+ width: @width;
+ .column { margin: @width; }
+}
+.content {
+ .nested-ruleset(600px);
+}
+
+//
+
+.same-var-name2(@radius) {
+ radius: @radius;
+}
+.same-var-name(@radius) {
+ .same-var-name2(@radius);
+}
+#same-var-name {
+ .same-var-name(5px);
+}
+
+//
+
+.var-inside () {
+ @var: 10px;
+ width: @var;
+}
+#var-inside { .var-inside; }
+.mix-inner (@var) {
+ border-width: @var;
+}
+
+.mix (@a: 10) {
+ .inner {
+ height: @a * 10;
+
+ .innest {
+ width: @a;
+ .mix-inner(@a * 2);
+ }
+ }
+}
+
+.class {
+ .mix(30);
+}
+.mixin () {
+ zero: 0;
+}
+.mixin (@a: 1px) {
+ one: 1;
+}
+.mixin (@a) {
+ one-req: 1;
+}
+.mixin (@a: 1px, @b: 2px) {
+ two: 2;
+}
+
+.mixin (@a, @b, @c) {
+ three-req: 3;
+}
+
+.mixin (@a: 1px, @b: 2px, @c: 3px) {
+ three: 3;
+}
+
+.zero {
+ .mixin();
+}
+
+.one {
+ .mixin(1);
+}
+
+.two {
+ .mixin(1, 2);
+}
+
+.three {
+ .mixin(1, 2, 3);
+}
+
+//
+
+.mixout ('left') {
+ left: 1;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbenchmarklessbenchmarkjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/benchmark/less-benchmark.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/benchmark/less-benchmark.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/benchmark/less-benchmark.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,47 @@
</span><ins>+var path = require('path'),
+ fs = require('fs'),
+ sys = require('util');
+
+var less = require('../lib/less');
+var file = path.join(__dirname, 'benchmark.less');
+
+if (process.argv[2]) { file = path.join(process.cwd(), process.argv[2]) }
+
+fs.readFile(file, 'utf8', function (e, data) {
+ var tree, css, start, end, total;
+
+ sys.puts("Benchmarking...\n", path.basename(file) + " (" +
+ parseInt(data.length / 1024) + " KB)", "");
+
+ start = new(Date);
+
+ new(less.Parser)({ optimization: 2 }).parse(data, function (err, tree) {
+ end = new(Date);
+
+ total = end - start;
+
+ sys.puts("Parsing: " +
+ total + " ms (" +
+ parseInt(1000 / total *
+ data.length / 1024) + " KB\/s)");
+
+ start = new(Date);
+ css = tree.toCSS();
+ end = new(Date);
+
+ sys.puts("Generation: " + (end - start) + " ms (" +
+ parseInt(1000 / (end - start) *
+ data.length / 1024) + " KB\/s)");
+
+ total += end - start;
+
+ sys.puts("Total: " + total + "ms (" +
+ parseInt(1000 / total * data.length / 1024) + " KB/s)");
+
+ if (err) {
+ less.writeError(err);
+ process.exit(3);
+ }
+ });
+});
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbinlessc"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/bin/lessc (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/bin/lessc (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/bin/lessc 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,160 @@
</span><ins>+#!/usr/bin/env node
+
+var path = require('path'),
+ fs = require('fs'),
+ sys = require('util'),
+ os = require('os');
+
+var less = require('../lib/less');
+var args = process.argv.slice(1);
+var options = {
+ compress: false,
+ yuicompress: false,
+ optimization: 1,
+ silent: false,
+ paths: [],
+ color: true,
+ strictImports: false
+};
+var continueProcessing = true,
+ currentErrorcode;
+
+// calling process.exit does not flush stdout always
+// so use this to set the exit code
+process.on('exit', function() { process.reallyExit(currentErrorcode) });
+
+args = args.filter(function (arg) {
+ var match;
+
+ if (match = arg.match(/^-I(.+)$/)) {
+ options.paths.push(match[1]);
+ return false;
+ }
+
+ if (match = arg.match(/^--?([a-z][0-9a-z-]*)(?:=([^\s]+))?$/i)) { arg = match[1] }
+ else { return arg }
+
+ switch (arg) {
+ case 'v':
+ case 'version':
+ sys.puts("lessc " + less.version.join('.') + " (LESS Compiler) [JavaScript]");
+ continueProcessing = false;
+ case 'verbose':
+ options.verbose = true;
+ break;
+ case 's':
+ case 'silent':
+ options.silent = true;
+ break;
+ case 'strict-imports':
+ options.strictImports = true;
+ break;
+ case 'h':
+ case 'help':
+ require('../lib/less/lessc_helper').printUsage();
+ continueProcessing = false;
+ case 'x':
+ case 'compress':
+ options.compress = true;
+ break;
+ case 'yui-compress':
+ options.yuicompress = true;
+ break;
+ case 'no-color':
+ options.color = false;
+ break;
+ case 'include-path':
+ options.paths = match[2].split(os.type().match(/Windows/) ? ';' : ':')
+ .map(function(p) {
+ if (p) {
+ return path.resolve(process.cwd(), p);
+ }
+ });
+ break;
+ case 'O0': options.optimization = 0; break;
+ case 'O1': options.optimization = 1; break;
+ case 'O2': options.optimization = 2; break;
+ case 'line-numbers':
+ options.dumpLineNumbers = match[2];
+ break;
+ }
+});
+
+if (!continueProcessing) {
+ return;
+}
+
+var input = args[1];
+if (input && input != '-') {
+ input = path.resolve(process.cwd(), input);
+}
+var output = args[2];
+if (output) {
+ output = path.resolve(process.cwd(), output);
+}
+
+if (! input) {
+ sys.puts("lessc: no input files");
+ sys.puts("");
+ require('../lib/less/lessc_helper').printUsage();
+ currentErrorcode = 1;
+ return;
+}
+
+var css, fd, tree;
+
+var parseLessFile = function (e, data) {
+ if (e) {
+ sys.puts("lessc: " + e.message);
+ currentErrorcode = 1;
+ return;
+ }
+
+ new(less.Parser)({
+ paths: [path.dirname(input)].concat(options.paths),
+ optimization: options.optimization,
+ filename: input,
+ strictImports: options.strictImports,
+ dumpLineNumbers: options.dumpLineNumbers
+ }).parse(data, function (err, tree) {
+ if (err) {
+ less.writeError(err, options);
+ currentErrorcode = 1;
+ return;
+ } else {
+ try {
+ css = tree.toCSS({
+ compress: options.compress,
+ yuicompress: options.yuicompress
+ });
+ if (output) {
+ fd = fs.openSync(output, "w");
+ fs.writeSync(fd, css, 0, "utf8");
+ fs.closeSync(fd);
+ } else {
+ sys.print(css);
+ }
+ } catch (e) {
+ less.writeError(e, options);
+ currentErrorcode = 2;
+ return;
+ }
+ }
+ });
+};
+
+if (input != '-') {
+ fs.readFile(input, 'utf-8', parseLessFile);
+} else {
+ process.stdin.resume();
+ process.stdin.setEncoding('utf8');
+
+ var buffer = '';
+ process.stdin.on('data', function(data) {
+ buffer += data;
+ });
+
+ process.stdin.on('end', function() {
+ parseLessFile(false, buffer);
+ });
+}
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/bin/lessc
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbuildamdjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/amd.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/amd.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/amd.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+// amd.js
+//
+// Define Less as an AMD module.
+if (typeof define === "function" && define.amd) {
+ define("less", [], function () { return less; } );
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbuildecma5js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/ecma-5.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/ecma-5.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/ecma-5.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,120 @@
</span><ins>+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbuildheaderjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/header.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/header.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/header.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+//
+// LESS - Leaner CSS v@VERSION
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbuildrequirerhinojs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/require-rhino.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/require-rhino.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/require-rhino.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+//
+// Stub out `require` in rhino
+//
+function require(arg) {
+ return less[arg.split('/')[1]];
+};
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessbuildrequirejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/require.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/require.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/build/require.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless110js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.0.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.0.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.0.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2695 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.0
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+ less = exports,
+ tree = require('less/tree');
+} else {
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ mime: env && env.mime, // MIME type of .less files
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (root) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+
+ callback(root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ chunks = [];
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam,
+ inString;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = i;
+
+ if (!inString && !inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ if (c === '{' && !inString && !inParam) { level ++;
+ chunk.push(c);
+ } else if (c === '}' && !inString && !inParam) { level --;
+ chunk.push(c);
+ chunks[++j] = chunk = [];
+ } else if (c === '(' && !inString && !inParam) {
+ chunk.push(c);
+ inParam = true;
+ } else if (c === ')' && !inString && inParam) {
+ chunk.push(c);
+ inParam = false;
+ } else {
+ if (c === '"' || c === "'" || c === '`') {
+ if (! inString) {
+ inString = c;
+ } else {
+ inString = inString === c ? false : inString;
+ }
+ }
+ chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ throw {
+ type: 'Syntax',
+ message: "Missing closing `}`",
+ filename: env.filename
+ };
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [];
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ lines = input.split('\n');
+ line = getLine(e.index);
+
+ for (var n = e.index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ throw {
+ type: e.type,
+ message: e.message,
+ filename: env.filename,
+ index: e.index,
+ line: typeof(line) === 'number' ? line + 1 : null,
+ callLine: e.call && (getLine(e.call) + 1),
+ callExtract: lines[getLine(e.call)],
+ stack: e.stack,
+ column: column,
+ extract: [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ]
+ };
+ }
+ if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+
+ function getLine(index) {
+ return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ name: "ParseError",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+ if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args;
+
+ if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+ if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value;
+
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ while (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ if (value = $(this.expression)) {
+ params.push({ name: param.name, value: value });
+ } else {
+ throw new(Error)("Expected value");
+ }
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ if (! $(',')) { break }
+ }
+ if (! $(')')) throw new(Error)("Expected )");
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset);
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c;
+
+ c = $(this.combinator);
+ e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+ if (e) { return new(tree.Element)(c, e) }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '&' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === ':' && input.charAt(i + 1) === ':') {
+ i += 2;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)('::');
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ if (match = /^([.#: \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+ i += match[0].length - 1;
+ selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+ } else {
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url)) &&
+ $(';')) {
+ return new(tree.Import)(path, imports);
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import'])) {
+ return value;
+ } else if (name = $(/^@media|@page|@-[-a-z]+/)) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (typeof(window) !== 'undefined') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (path.charAt(0) !== '/' && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math.round(number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math.round(n);
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "math functions take numbers as parameters"
+ };
+ }
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args) {
+ this.name = name;
+ this.args = args;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ return tree.functions[this.name].apply(tree.functions, args);
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else if (rgb.length == 8) {
+ this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
+ this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+ this.name = name;
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+ this.value = value.trim();
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ ':' : ' :',
+ '::': '::',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else {
+ return this.value[0].eval(env);
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(' ');
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+ var that = this;
+
+ this._path = path;
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (root) {
+ if (! root) {
+ throw new(Error)("Error parsing " + that.path);
+ }
+ that.root = root;
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function () {
+ if (this.css) {
+ return "@import " + this._path.toCSS() + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset;
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return ruleset.rules;
+ }
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.evaluated;
+ } else {
+ return JSON.stringify(this.evaluated);
+ }
+ },
+ eval: function (env) {
+ var result,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return new(tree.Variable)('@' + name).eval(env).value;
+ });
+
+ expression = new(Function)('return (' + expression + ')');
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ this.evaluated = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ return this;
+ }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(this.arguments, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index };
+ }
+ }
+ }
+ throw { message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ eval: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+ for (var i = 0, val; i < this.params.length; i++) {
+ if (this.params[i].name) {
+ if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+ } else {
+ throw { message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments)));
+
+ return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len;
+
+ if (argsLength < this.required) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ this.value = this.value.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return new(tree.Variable)('@' + name).eval(env).value;
+ }).replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, this.index, true).eval(env).toCSS();
+ });
+ return this;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + ";";
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+ ruleset.root = this.root;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > 1) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ for (var s = 0; s < this.selectors.length; s++) {
+ for (var c = 0; c < context.length; c++) {
+ paths.push(context[c].concat([this.selectors[s]]));
+ }
+ }
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ if (this.elements[0].value === other.elements[0].value) {
+ return true;
+ } else {
+ return false;
+ }
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { message: "variable " + name + " is undefined",
+ index: this.index };
+ }
+ }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:' ||
+ location.protocol === 'chrome:' ||
+ location.protocol === 'chrome-extension:' ||
+ location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (root, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (root, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+ styles[i].type = 'text/css';
+ styles[i].innerHTML = tree.toCSS();
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^(https?|file):/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ css.media = sheet.media || 'screen';
+ css.id = id;
+ document.getElementsByTagName('head')[0].appendChild(css);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? false : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol) {
+ if (xhr.status === 0) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+
+ var template = ['<ul>',
+ '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+ '<li><label>[0]</label><pre>{current}</pre></li>',
+ '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+ '</ul>'].join('\n');
+
+ var elem = document.createElement('div'), timer, content;
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p><a href="' + href + '">' + href + "</a> ";
+
+ if (e.extract) {
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ template.replace(/\[(-?\d)\]/g, function (_, i) {
+ return (parseInt(e.line) + parseInt(i)) || '';
+ }).replace(/\{(\d)\}/g, function (_, i) {
+ return e.extract[parseInt(i)] || '';
+ }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+ e.extract[1].slice(e.column) + '</span>');
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #ee4444;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.ctx {',
+ 'color: #dd4444;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless110minjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.0.min.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.0.min.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.0.min.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.0
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+//
+// LESS - Leaner CSS v1.1.0
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function v(a,b){var c="less-error-message:"+p(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p><a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+":</p>"+e.replace(/\[(-?\d)\]/g,function(b,c){return parseInt(a.line)+parseInt(c)||""}).replace(/\{(\d)\}/g,function(b,c){return a.extract[parseInt(c)]||"&q
uot;}).replace(/\{current\}/,a.extract[1].slice(0,a.column)+'<span class="error">'+a.extract[1].slice(a.column)+"</span>")),f.innerHTML=h,q([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #ee4444;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.ctx {","color: #dd4444;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","
;color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=setInterval(function(){document.body&&(document.getElementById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}function u(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: &quo
t;+a)}function t(a){return a&&a.parentNode.removeChild(a)}function s(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){u("browser doesn't support AJAX.");return null}}function r(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var f=s(),h=g?!1:d.async;typeof f.overrideMimeType=="function"&&f.overrideMimeType("text/css"),f.open("GET",a,h),f.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),f.send(null),g?f.status===0?c(f.responseText):e(f.status,a):h?f.onreadystatechange=function(){f.readyState==4&&i(f,c,e)}:i(f,c,e)}function q(a,b,c){var d,e=b.href?b.href.replace(/\?.*$/,""):"",f="less:"+(b.title||p(e));(d=document.getElementById(f))===null&
&(d=document.createElement("style"),d.type="text/css",d.media=b.media||"screen",d.id=f,document.getElementsByTagName("head")[0].appendChild(d));if(d.styleSheet)try{d.styleSheet.cssText=a}catch(g){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(a){d.childNodes.length>0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&h&&(u("saving "+e+" to cache."),h.setItem(e,a),h.setItem(e+":timestamp",c))}function p(a){return a.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\?.*$/,"").replace(/\.[^\.\/]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function o(b,c,e,f){var g=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/,""),j=h&&h.getItem(i),k=h&&h.getItem(i+":ti
mestamp"),l={css:j,timestamp:k};/^(https?|file):/.test(i)||(i.charAt(0)=="/"?i=a.location.protocol+"//"+a.location.host+i:i=g.slice(0,g.lastIndexOf("/")+1)+i),r(b.href,b.type,function(a,g){if(!e&&l&&g&&(new Date(g)).valueOf()===(new Date(l.timestamp)).valueOf())q(l.css,b),c(null,b,{local:!0,remaining:f});else try{(new d.Parser({optimization:d.optimization,paths:[i.replace(/[\w\.-]+$/,"")],mime:b.type})).parse(a,function(a,d){if(a)return v(a,i);try{c(d,b,{local:!1,lastModified:g,remaining:f}),t(document.getElementById("less-error-message:"+p(i)))}catch(a){v(a,i)}})}catch(h){v(h,i)}},function(a,b){throw new Error("Couldn't load "+b+" ("+a+")")})}function n(a,b){for(var c=0;c<d.sheets.length;c++)o(d.sheets[c],a,b,d.sheets.length-(c+1))}function m(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(k)&&(new d.Parser).p
arse(a[b].innerHTML||"",function(c,d){a[b].type="text/css",a[b].innerHTML=d.toCSS()})}function c(b){return a.less[b.split("/")[1]]}Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d<c;d++)d in this&&a.call(b,this[d],d,this)}),Array.prototype.map||(Array.prototype.map=function(a){var b=this.length>>>0,c=Array(b),d=arguments[1];for(var e=0;e<b;e++)e in this&&(c[e]=a.call(d,this[e],e,this));return c}),Array.prototype.filter||(Array.prototype.filter=function(a){var b=[],c=arguments[1];for(var d=0;d<this.length;d++)a.call(c,this[d])&&b.push(this[d]);return b}),Array.prototype.reduce||(Array.prototype.reduce=function(a){var b=this.length>>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.leng
th>=2)var d=arguments[1];else for(;;){if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}for(;c<b;c++)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){var b=this.length,c=arguments[1]||0;if(!b)return-1;if(c>=b)return-1;c<0&&(c+=b);for(;c<b;c++){if(!Object.prototype.hasOwnProperty.call(this,c))continue;if(a===this[c])return c}return-1}),Object.keys||(Object.keys=function(a){var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}),String.prototype.trim||(String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")});var d,e;typeof a=="undefined"?(d=exports,e=c("less/tree")):(typeof a.less=="undefined"&&(a.less={}),d=a.less,e=a.less.tree={}),d.Parser=function(a){function t(a){return typeof a=="string"?b.charAt(c)===a:a.test(j[f])?!0:!1
}function s(a){var d,e,g,h,i,m,n,o;if(a instanceof Function)return a.call(l.parsers);if(typeof a=="string")d=b.charAt(c)===a?a:null,g=1,r();else{r();if(d=a.exec(j[f]))g=d[0].length;else return null}if(d){o=c+=g,m=c+j[f].length-g;while(c<m){h=b.charCodeAt(c);if(h!==32&&h!==10&&h!==9)break;c++}j[f]=j[f].slice(g+(c-o)),k=c,j[f].length===0&&f<j.length-1&&f++;return typeof d=="string"?d:d.length===1?d[0]:d}}function r(){c>k&&(j[f]=j[f].slice(c-k),k=c)}function q(){j[f]=g,c=h,k=c}function p(){g=j[f],h=c,k=c}var b,c,f,g,h,i,j,k,l,m=this,n=function(){},o=this.imports={paths:a&&a.paths||[],queue:[],files:{},mime:a&&a.mime,push:function(b,c){var e=this;this.queue.push(b),d.Parser.importer(b,this.paths,function(a){e.queue.splice(e.queue.indexOf(b),1),e.files[b]=a,c(a),e.queue.length===0&&n()},a)}};this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.fi
lename=this.env.filename||null;return l={imports:o,parse:function(d,g){var h,l,m,o,p,q,r=[],t,u=null;c=f=k=i=0,j=[],b=d.replace(/\r\n/g,"\n"),j=function(c){var d=0,e=/[^"'`\{\}\/\(\)]+/g,f=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,g=0,h,i=c[0],j,k;for(var l=0,m,n;l<b.length;l++){e.lastIndex=l,(h=e.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0])),m=b.charAt(l),f.lastIndex=l,!k&&!j&&m==="/"&&(n=b.charAt(l+1),(n==="/"||n==="*")&&(h=f.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0]),m=b.charAt(l)));if(m==="{"&&!k&&!j)g++,i.push(m);else if(m==="}"&&!k&&!j)g--,i.push(m),c[++d]=i=[];else if(m==="("&&!k&&!j)i.push(m),j=!0;else if(m===")"&&!k&&j)i.push(m),j=!1;else{if(m==='"'||m==="'"||m==="`")k?k=k===m?!1:k:k=m;i.push(m)}}if(g>0)throw{type:"S
yntax",message:"Missing closing `}`",filename:a.filename};return c.map(function(a){return a.join("")})}([[]]),h=new e.Ruleset([],s(this.parsers.primary)),h.root=!0,h.toCSS=function(c){var d,f,g;return function(g,h){function n(a){return a?(b.slice(0,a).match(/\n/g)||"").length:null}var i=[];g=g||{},typeof h=="object"&&!Array.isArray(h)&&(h=Object.keys(h).map(function(a){var b=h[a];b instanceof e.Value||(b instanceof e.Expression||(b=new e.Expression([b])),b=new e.Value([b]));return new e.Rule("@"+a,b,!1,0)}),i=[new e.Ruleset(null,h)]);try{var j=c.call(this,{frames:i}).toCSS([],{compress:g.compress||!1})}catch(k){f=b.split("\n"),d=n(k.index);for(var l=k.index,m=-1;l>=0&&b.charAt(l)!=="\n";l--)m++;throw{type:k.type,message:k.message,filename:a.filename,index:k.index,line:typeof d=="number"?d+1:null,callLine:k.call&&n(k.call)+1,callExtract:f[n(k.call)],stack:k.stack,co
lumn:m,extract:[f[d-1],f[d],f[d+1]]}}return g.compress?j.replace(/(\s)+/g,"$1"):j}}(h.eval);if(c<b.length-1){c=i,q=b.split("\n"),p=(b.slice(0,c).match(/\n/g)||"").length+1;for(var v=c,w=-1;v>=0&&b.charAt(v)!=="\n";v--)w++;u={name:"ParseError",message:"Syntax Error on line "+p,index:c,filename:a.filename,line:p,column:w,extract:[q[p-2],q[p-1],q[p]]}}this.imports.queue.length>0?n=function(){g(u,h)}:g(u,h)},parsers:{primary:function(){var a,b=[];while((a=s(this.mixin.definition)||s(this.rule)||s(this.ruleset)||s(this.mixin.call)||s(this.comment)||s(this.directive))||s(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(b.charAt(c)==="/"){if(b.charAt(c+1)==="/")return new e.Comment(s(/^\/\/.*/),!0);if(a=s(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new e.Comment(a)}},entities:{quoted:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)==='&q
uot;'||b.charAt(d)==="'"){f&&s("~");if(a=s(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new e.Quoted(a[0],a[1]||a[2],f)}},keyword:function(){var a;if(a=s(/^[A-Za-z-]+/))return new e.Keyword(a)},call:function(){var a,b;if(!!(a=/^([\w-]+|%)\(/.exec(j[f]))){a=a[1].toLowerCase();if(a==="url")return null;c+=a.length;if(a==="alpha")return s(this.alpha);s("("),b=s(this.entities.arguments);if(!s(")"))return;if(a)return new e.Call(a,b)}},arguments:function(){var a=[],b;while(b=s(this.expression)){a.push(b);if(!s(","))break}return a},literal:function(){return s(this.entities.dimension)||s(this.entities.color)||s(this.entities.quoted)},url:function(){var a;if(b.charAt(c)==="u"&&!!s(/^url\(/)){a=s(this.entities.quoted)||s(this.entities.variable)||s(this.entities.dataURI)||s(/^[-\w%@$\/.&=:;#+?~]+/)||"";if(!s(")"))throw new Error("missing closi
ng ) for url()");return new e.URL(a.value||a.data||a instanceof e.Variable?a:new e.Anonymous(a),o.paths)}},dataURI:function(){var a;if(s(/^data:/)){a={},a.mime=s(/^[^\/]+\/[^,;)]+/)||"",a.charset=s(/^;\s*charset=[^,;)]+/)||"",a.base64=s(/^;\s*base64/)||"",a.data=s(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var a,d=c;if(b.charAt(c)==="@"&&(a=s(/^@@?[\w-]+/)))return new e.Variable(a,d)},color:function(){var a;if(b.charAt(c)==="#"&&(a=s(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new e.Color(a[1])},dimension:function(){var a,d=b.charCodeAt(c);if(!(d>57||d<45||d===47))if(a=s(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new e.Dimension(a[1],a[2])},javascript:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)==="`"){f&&s("~");if(a=s(/^`([^`]*)`/))return new e.JavaScript(a[1],c,f)}}},variable:function(){var a
;if(b.charAt(c)==="@"&&(a=s(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!!t(/^[@\w.%-]+\/[@\w.-]+/)&&(a=s(this.entity))&&s("/")&&(b=s(this.entity)))return new e.Shorthand(a,b)},mixin:{call:function(){var a=[],d,f,g,h=c,i=b.charAt(c);if(i==="."||i==="#"){while(d=s(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))a.push(new e.Element(f,d)),f=s(">");s("(")&&(g=s(this.entities.arguments))&&s(")");if(a.length>0&&(s(";")||t("}")))return new e.mixin.Call(a,g,h)}},definition:function(){var a,d=[],f,g,h,i;if(!(b.charAt(c)!=="."&&b.charAt(c)!=="#"||t(/^[^{]*(;|})/)))if(f=s(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=f[1];while(h=s(this.entities.variable)||s(this.entities.literal)||s(this.entities.keyword)){if(h instanceof e.Variable)if(s(":"))if(i=s(this.e
xpression))d.push({name:h.name,value:i});else throw new Error("Expected value");else d.push({name:h.name});else d.push({value:h});if(!s(","))break}if(!s(")"))throw new Error("Expected )");g=s(this.block);if(g)return new e.mixin.Definition(a,d,g)}}},entity:function(){return s(this.entities.literal)||s(this.entities.variable)||s(this.entities.url)||s(this.entities.call)||s(this.entities.keyword)||s(this.entities.javascript)||s(this.comment)},end:function(){return s(";")||t("}")},alpha:function(){var a;if(!!s(/^opacity=/i))if(a=s(/^\d+/)||s(this.entities.variable)){if(!s(")"))throw new Error("missing closing ) for alpha()");return new e.Alpha(a)}},element:function(){var a,b,c;c=s(this.combinator),a=s(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||s("*")||s(this.attribute)||s(/^\([^)@]+\)/);if(a)return new e.Element(c,a)},combinator:function(){var a,d=b.charAt(c);if(d===">
;"||d==="&"||d==="+"||d==="~"){c++;while(b.charAt(c)===" ")c++;return new e.Combinator(d)}if(d===":"&&b.charAt(c+1)===":"){c+=2;while(b.charAt(c)===" ")c++;return new e.Combinator("::")}return b.charAt(c-1)===" "?new e.Combinator(" "):new e.Combinator(null)},selector:function(){var a,d,f=[],g,h;while(d=s(this.element)){g=b.charAt(c),f.push(d);if(g==="{"||g==="}"||g===";"||g===",")break}if(f.length>0)return new e.Selector(f)},tag:function(){return s(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||s("*")},attribute:function(){var a="",b,c,d;if(!!s("[")){if(b=s(/^[a-zA-Z-]+/)||s(this.entities.quoted))(d=s(/^[|~*$^]?=/))&&(c=s(this.entities.quoted)||s(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!s("]"))return;if(a)return"["+a+"]"}},block:function(){var a;if(s
("{")&&(a=s(this.primary))&&s("}"))return a},ruleset:function(){var a=[],b,d,g;p();if(g=/^([.#: \w-]+)[\s\n]*\{/.exec(j[f]))c+=g[0].length-1,a=[new e.Selector([new e.Element(null,g[1])])];else while(b=s(this.selector)){a.push(b),s(this.comment);if(!s(","))break;s(this.comment)}if(a.length>0&&(d=s(this.block)))return new e.Ruleset(a,d);i=c,q()},rule:function(){var a,d,g=b.charAt(c),k,l;p();if(g!=="."&&g!=="#"&&g!=="&")if(a=s(this.variable)||s(this.property)){a.charAt(0)!="@"&&(l=/^([^@+\/'"*`(;{}-]*);/.exec(j[f]))?(c+=l[0].length-1,d=new e.Anonymous(l[1])):a==="font"?d=s(this.font):d=s(this.value),k=s(this.important);if(d&&s(this.end))return new e.Rule(a,d,k,h);i=c,q()}},"import":function(){var a;if(s(/^@import\s+/)&&(a=s(this.entities.quoted)||s(this.entities.url))&&s(";"))return new e.Import(a,o)},dir
ective:function(){var a,d,f,g;if(b.charAt(c)==="@"){if(d=s(this["import"]))return d;if(a=s(/^@media|@page|@-[-a-z]+/)){g=(s(/^[^{]+/)||"").trim();if(f=s(this.block))return new e.Directive(a+" "+g,f)}else if(a=s(/^@[-a-z]+/))if(a==="@font-face"){if(f=s(this.block))return new e.Directive(a,f)}else if((d=s(this.entity))&&s(";"))return new e.Directive(a,d)}},font:function(){var a=[],b=[],c,d,f,g;while(g=s(this.shorthand)||s(this.entity))b.push(g);a.push(new e.Expression(b));if(s(","))while(g=s(this.expression)){a.push(g);if(!s(","))break}return new e.Value(a)},value:function(){var a,b=[],c;while(a=s(this.expression)){b.push(a);if(!s(","))break}if(b.length>0)return new e.Value(b)},important:function(){if(b.charAt(c)==="!")return s(/^! *important/)},sub:function(){var a;if(s("(")&&(a=s(this.expression))&&s(")"))return a},multiplication:function
(){var a,b,c,d;if(a=s(this.operand)){while((c=s("/")||s("*"))&&(b=s(this.operand)))d=new e.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,d,f,g;if(a=s(this.multiplication)){while((f=s(/^[-+]\s+/)||b.charAt(c-1)!=" "&&(s("+")||s("-")))&&(d=s(this.multiplication)))g=new e.Operation(f,[g||a,d]);return g||a}},operand:function(){var a,d=b.charAt(c+1);b.charAt(c)==="-"&&(d==="@"||d==="(")&&(a=s("-"));var f=s(this.sub)||s(this.entities.dimension)||s(this.entities.color)||s(this.entities.variable)||s(this.entities.call);return a?new e.Operation("*",[new e.Dimension(-1),f]):f},expression:function(){var a,b,c=[],d;while(a=s(this.addition)||s(this.entity))c.push(a);if(c.length>0)return new e.Expression(c)},property:function(){var a;if(a=s(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}},typeof a!="undefined"&&(d.Parser.importe
r=function(a,b,c,d){a.charAt(0)!=="/"&&b.length>0&&(a=b[0]+a),o({href:a,title:a,type:d.mime},c,!0)}),function(a){function d(a){return Math.min(1,Math.max(0,a))}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){a=a<0?a+1:a>1?a-1:a;return a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(M
ath.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();e.s+=c.value/100,e.s=d(e.s);return b(e)},desaturate:function(a,c){var e=a.toHSL();e.s-=c.value/100,e.s=d(e.s);return b(e)},lighten:function(a,c){var e=a.toHSL();e.l+=c.value/100,e.l=d(e.l);return b(e)},darken:function(a,c){var e=a.toHSL();e.l-=c.value/100,e.l=d(e.l);return b(e)},fadein:function(a,c){var e=a.toHSL();e.a+=c.value/100,e.a=d(e.a);return b(e)},fadeout:function(a,c){var e=a.toHSL();e.a-=c.value/100,e.a=d(e.a);return b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;d.h=e<0?360+e:e;return b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb
[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e<c.length;e++)d=d.replace(/%[sda]/i,function(a){var b=a.match(/s/i)?c[e].value:c[e].toCSS();return a.match(/[A-Z]$/)?encodeURIComponent(b):b});d=d.replace(/%%/g,"%");return new a.Quoted('"'+d+'"',d)},round:function(b){if(b instanceof a.Dimension)return new a.Dimension(Math.round(c(b)),b.unit);if(typeof b=="number")return Math.round(b);throw{error:"RuntimeError",message:"math functions take numbers a
s parameters"}}}}(c("less/tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(){return this}}}(c("less/tree")),function(a){a.Anonymous=function(a){this.value=a.value||a},a.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this}}}(c("less/tree")),function(a){a.Call=function(a,b){this.name=a,this.args=b},a.Call.prototype={eval:function(b){var c=this.args.map(function(a){return a.eval(b)});return this.name in a.functions?a.functions[this.name].apply(a.functions,c):new a.Anonymous(this.name+"("+c.map(function(a){return a.toCSS()}).join(", ")+")")},toCSS:function(a){return this.eval(a).toCSS()}}}(c("less/tree")),function(a){a.Color=function(a,b){Array.isArray(a)?this.rgb=a:a.length==6?this.rgb=a.match(/.{2}/g).map(function(a){return parse
Int(a,16)}):a.length==8?(this.alpha=parseInt(a.substring(0,2),16)/255,this.rgb=a.substr(2).match(/.{2}/g).map(function(a){return parseInt(a,16)})):this.rgb=a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha=typeof b=="number"?b:1},a.Color.prototype={eval:function(){return this},toCSS:function(){return this.alpha<1?"rgba("+this.rgb.map(function(a){return Math.round(a)}).concat(this.alpha).join(", ")+")":"#"+this.rgb.map(function(a){a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16);return a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);swi
tch(e){case a:g=(b-c)/j+(b<c?6:0);break;case b:g=(c-a)/j+2;break;case c:g=(a-b)/j+4}g/=6}return{h:g*360,s:h,l:i,a:d}}}}(c("less/tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("less/tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)}}}(c("less/tree")),function(a){a.Directive=function(b,c){this.name=b,Array.isArray(c)?this.ruleset=new a.Ruleset([],c):this.value=c},a.Directive.prototype={toCSS:function(a,b){if(this.ruleset){this.ruleset.root=!0;return this.name+(b.compress?"{":" {\n "
;)+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n ")+(b.compress?"}":"\n}\n")}return this.name+" "+this.value.toCSS()+";\n"},eval:function(a){a.frames.unshift(this),this.ruleset=this.ruleset&&this.ruleset.eval(a),a.frames.shift();return this},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(c("less/tree")),function(a){a.Element=function(b,c){this.combinator=b instanceof a.Combinator?b:new a.Combinator(b),this.value=c.trim()},a.Element.prototype.toCSS=function(a){return this.combinator.toCSS(a||{})+this.value},a.Combinator=function(a){a===" "?this.value=" ":this.value=a?a.trim():""},a.Combinator.prototype.toCSS=function(a){return{"":""," ":" ","&"
:"",":":" :","::":"::","+":a.compress?"+":" + ","~":a.compress?"~":" ~ ",">":a.compress?">":" > "}[this.value]}}(c("less/tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value[0].eval(b)},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(" ")}}}(c("less/tree")),function(a){a.Import=function(b,c){var d=this;this._path=b,b instanceof a.Quoted?this.path=/\.(le?|c)ss$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value||b.value,this.css=/css$/.test(this.path),this.css||c.push(this.path,function(a){if(!a)throw new Error("Error parsing "+d.path);d.root=a})},a.Import.prototype={toCSS:function(){return this.css
?"@import "+this._path.toCSS()+";\n":""},eval:function(b){var c;if(this.css)return this;c=new a.Ruleset(null,this.root.rules.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));return c.rules}}}(c("less/tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={toCSS:function(){return this.escaped?this.evaluated:JSON.stringify(this.evaluated)},eval:function(b){var c,d={},e=this.expression.replace(/@\{([\w-]+)\}/g,function(c,d){return(new a.Variable("@"+d)).eval(b).value});e=new Function("return ("+e+")");for(var f in b.frames[0].variables())d[f.slice(1)]={value:b.frames[0].variables()[f].value,toJS:function(){return this.value.eval(b).toCSS()}};try{this.evaluated=e.call(d)}catch(g){throw{message:"JavaScript evaluation error: '"+g.name+":
"+g.message+"'",index:this.index}}return this}}}(c("less/tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value}}}(c("less/tree")),function(a){a.mixin={},a.mixin.Call=function(b,c,d){this.selector=new a.Selector(b),this.arguments=c,this.index=d},a.mixin.Call.prototype={eval:function(a){var b,c=[],d=!1;for(var e=0;e<a.frames.length;e++)if((b=a.frames[e].find(this.selector)).length>0){for(var f=0;f<b.length;f++)if(b[f].match(this.arguments,a))try{Array.prototype.push.apply(c,b[f].eval(a,this.arguments).rules),d=!0}catch(g){throw{message:g.message,index:g.index,stack:g.stack,call:this.index}}if(d)return c;throw{message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(a){return a.toCSS()}).join(", ")+")`",index:this.index}}throw{message:this.selector.toCSS().trim()+&
quot; is undefined",index:this.index}}},a.mixin.Definition=function(b,c,d){this.name=b,this.selectors=[new a.Selector([new a.Element(null,b)])],this.params=c,this.arity=c.length,this.rules=d,this._lookups={},this.required=c.reduce(function(a,b){return!b.name||b.name&&!b.value?a+1:a},0),this.parent=a.Ruleset.prototype,this.frames=[]},a.mixin.Definition.prototype={toCSS:function(){return""},variable:function(a){return this.parent.variable.call(this,a)},variables:function(){return this.parent.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},eval:function(b,c){var d=new a.Ruleset(null,[]),e,f=[];for(var g=0,h;g<this.params.length;g++)if(this.params[g].name)if(h=c&&c[g]||this.params[g].value)d.rules.unshift(new a.Rule(this.params[g].name,h.eval(b)));else throw{message:"wrong number of arguments for "+this.name+" ("+c.length+" for &quo
t;+this.arity+")"};for(var g=0;g<Math.max(this.params.length,c&&c.length);g++)f.push(c[g]||this.params[g].value);d.rules.unshift(new a.Rule("@arguments",new a.Expression(f)));return(new a.Ruleset(null,this.rules.slice(0))).eval({frames:[this,d].concat(this.frames,b.frames)})},match:function(a,b){var c=a&&a.length||0,d;if(c<this.required)return!1;if(this.required>0&&c>this.params.length)return!1;d=Math.min(c,this.arity);for(var e=0;e<d;e++)if(!this.params[e].name&&a[e].eval(b).toCSS()!=this.params[e].value.eval(b).toCSS())return!1;return!0}}}(c("less/tree")),function(a){a.Operation=function(a,b){this.op=a.trim(),this.operands=b},a.Operation.prototype.eval=function(b){var c=this.operands[0].eval(b),d=this.operands[1].eval(b),e;if(c instanceof a.Dimension&&d instanceof a.Color)if(this.op==="*"||this.op==="+")e=d,d=c,c=e;else throw{name:"OperationError",message:"Can't
substract or divide a color from a number"};return c.operate(this.op,d)},a.operate=function(a,b,c){switch(a){case"+":return b+c;case"-":return b-c;case"*":return b*c;case"/":return b/c}}}(c("less/tree")),function(a){a.Quoted=function(a,b,c,d){this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d},a.Quoted.prototype={toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(b){this.value=this.value.replace(/@\{([\w-]+)\}/g,function(c,d){return(new a.Variable("@"+d)).eval(b).value}).replace(/`([^`]+)`/g,function(c,d){return(new a.JavaScript(d,this.index,!0)).eval(b).toCSS()});return this}}}(c("less/tree")),function(a){a.Rule=function(b,c,d,e){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.index=e,b.charAt(0)==="@"?this.variable=!0:this.variable=!1},a.Rule.prototype.to
CSS=function(a){return this.variable?"":this.name+(a.compress?":":": ")+this.value.toCSS(a)+this.important+";"},a.Rule.prototype.eval=function(b){return new a.Rule(this.name,this.value.eval(b),this.important,this.index)},a.Shorthand=function(a,b){this.a=a,this.b=b},a.Shorthand.prototype={toCSS:function(a){return this.a.toCSS(a)+"/"+this.b.toCSS(a)},eval:function(){return this}}}(c("less/tree")),function(a){a.Ruleset=function(a,b){this.selectors=a,this.rules=b,this._lookups={}},a.Ruleset.prototype={eval:function(b){var c=new a.Ruleset(this.selectors,this.rules.slice(0));c.root=this.root,b.frames.unshift(c);if(c.root)for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Definition&&(c.rules[d].frames=b.frames.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d
]instanceof a.mixin.Call&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0,e;d<c.rules.length;d++)e=c.rules[d],e instanceof a.mixin.Definition||(c.rules[d]=e.eval?e.eval(b):e);b.frames.shift();return c},match:function(a){return!a||a.length===0},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(b,c){c instanceof a.Rule&&c.variable===!0&&(b[c.name]=c);return b},{})},variable:function(a){return this.variables()[a]},rulesets:function(){return this._rulesets?this._rulesets:this._rulesets=this.rules.filter(function(b){return b instanceof a.Ruleset||b instanceof a.mixin.Definition})},find:function(b,c){c=c||this;var d=[],e,f,g=b.toCSS();if(g in this._lookups)return this._lookups[g];this.rulesets().forEach(function(e){if(e!==c)for(var g=0;g<e.selectors.length;g++)if(f=b.match(e.selectors[g])){b.elements.length>1?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements
.slice(1)),c)):d.push(e);break}});return this._lookups[g]=d},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;if(!this.root)if(b.length===0)g=this.selectors.map(function(a){return[a]});else for(var j=0;j<this.selectors.length;j++)for(var k=0;k<b.length;k++)g.push(b[k].concat([this.selectors[j]]));for(var l=0;l<this.rules.length;l++)i=this.rules[l],i.rules||i instanceof a.Directive?f.push(i.toCSS(g,c)):i instanceof a.Comment?i.silent||(this.root?f.push(i.toCSS(c)):e.push(i.toCSS(c))):i.toCSS&&!i.variable?e.push(i.toCSS(c)):i.value&&!i.variable&&e.push(i.value.toString());f=f.join(""),this.root?d.push(e.join(c.compress?"":"\n")):e.length>0&&(h=g.map(function(a){return a.map(function(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":g.length>3?",\n":", "),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.
compress?"}":"\n}\n"))),d.push(f);return d.join("")+(c.compress?"\n":"")}}}(c("less/tree")),function(a){a.Selector=function(a){this.elements=a,this.elements[0].combinator.value===""&&(this.elements[0].combinator.value=" ")},a.Selector.prototype.match=function(a){return this.elements[0].value===a.elements[0].value?!0:!1},a.Selector.prototype.toCSS=function(a){if(this._css)return this._css;return this._css=this.elements.map(function(b){return typeof b=="string"?" "+b.trim():b.toCSS(a)}).join("")}}(c("less/tree")),function(b){b.URL=function(b,c){b.data?this.attrs=b:(!/^(?:https?:\/|file:\/|data:\/)?\//.test(b.value)&&c.length>0&&typeof a!="undefined"&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?&q
uot;data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("less/tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("less/tree")),function(a){a.Variable=function(a,b){this.name=a,this.index=b},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{message:"variable "+e+" is undefined",index:this.index}}}}(c("l
ess/tree")),c("less/tree").find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null};var g=location.protocol==="file:"||location.protocol==="chrome:"||location.
+protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||g?"development":"production"),d.async=!1,d.poll=d.poll||(g?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&n(function(a,b,c){a&&q(a.toCSS(),b,c.lastModified)})},d.poll)):d.optimization=3;var h;try{h=typeof a.localStorage=="undefined"?null:a.localStorage}catch(i){h=null}var j=document.getElementsByTagName("link"),k=/^text\/(x-)?less$/;d.sheets=[];for(var l=0;l<j.length;l++)(j[l].rel==="stylesheet/less"||j[l].rel.match(/stylesheet/)&&j[l].type.match(k))&&d.she
ets.push(j[l]);d.refresh=function(a){var b,c;b=c=new Date,n(function(a,d,e){e.local?u("loading "+d.href+" from cache."):(u("parsed "+d.href+" successfully."),q(a.toCSS(),d,e.lastModified)),u("css for "+d.href+" generated in "+(new Date-c)+"ms"),e.remaining===0&&u("css generated in "+(new Date-b)+"ms"),c=new Date},a),m()},d.refreshStyles=m,d.refresh(d.env==="development")})(window)
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless111js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.1.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.1.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.1.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2710 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.1
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+ less = exports,
+ tree = require('less/tree');
+} else {
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ mime: env && env.mime, // MIME type of .less files
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (root) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+
+ callback(root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ chunks = [];
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam,
+ inString;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = i;
+
+ if (!inString && !inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ if (c === '{' && !inString && !inParam) { level ++;
+ chunk.push(c);
+ } else if (c === '}' && !inString && !inParam) { level --;
+ chunk.push(c);
+ chunks[++j] = chunk = [];
+ } else if (c === '(' && !inString && !inParam) {
+ chunk.push(c);
+ inParam = true;
+ } else if (c === ')' && !inString && inParam) {
+ chunk.push(c);
+ inParam = false;
+ } else {
+ if (c === '"' || c === "'" || c === '`') {
+ if (! inString) {
+ inString = c;
+ } else {
+ inString = inString === c ? false : inString;
+ }
+ }
+ chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ throw {
+ type: 'Syntax',
+ message: "Missing closing `}`",
+ filename: env.filename
+ };
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [];
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ lines = input.split('\n');
+ line = getLine(e.index);
+
+ for (var n = e.index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ throw {
+ type: e.type,
+ message: e.message,
+ filename: env.filename,
+ index: e.index,
+ line: typeof(line) === 'number' ? line + 1 : null,
+ callLine: e.call && (getLine(e.call) + 1),
+ callExtract: lines[getLine(e.call)],
+ stack: e.stack,
+ column: column,
+ extract: [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ]
+ };
+ }
+ if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+
+ function getLine(index) {
+ return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ name: "ParseError",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+ if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args;
+
+ if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+ if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value;
+
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ while (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ if (value = $(this.expression)) {
+ params.push({ name: param.name, value: value });
+ } else {
+ throw new(Error)("Expected value");
+ }
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ if (! $(',')) { break }
+ }
+ if (! $(')')) throw new(Error)("Expected )");
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset);
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c;
+
+ c = $(this.combinator);
+ e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+ if (e) { return new(tree.Element)(c, e) }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '&' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === ':' && input.charAt(i + 1) === ':') {
+ i += 2;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)('::');
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ if (match = /^([.#: \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+ i += match[0].length - 1;
+ selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+ } else {
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url)) &&
+ $(';')) {
+ return new(tree.Import)(path, imports);
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import'])) {
+ return value;
+ } else if (name = $(/^@media|@page|@-[-a-z]+/)) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (typeof(window) !== 'undefined') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (path.charAt(0) !== '/' && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math.round(number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math.round(n);
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "math functions take numbers as parameters"
+ };
+ }
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args) {
+ this.name = name;
+ this.args = args;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ return tree.functions[this.name].apply(tree.functions, args);
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else if (rgb.length == 8) {
+ this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
+ this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+ this.name = name;
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+ this.value = value.trim();
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ ':' : ' :',
+ '::': '::',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(' ');
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+ var that = this;
+
+ this._path = path;
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (root) {
+ if (! root) {
+ throw new(Error)("Error parsing " + that.path);
+ }
+ that.root = root;
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function () {
+ if (this.css) {
+ return "@import " + this._path.toCSS() + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset;
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return ruleset.rules;
+ }
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(this.arguments, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index };
+ }
+ }
+ }
+ throw { message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ eval: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+ for (var i = 0, val; i < this.params.length; i++) {
+ if (this.params[i].name) {
+ if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+ } else {
+ throw { message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len;
+
+ if (argsLength < this.required) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ this.value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return new(tree.Variable)('@' + name, that.index).eval(env).value;
+ });
+ return this;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + ";";
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+ ruleset.root = this.root;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > 1) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ for (var s = 0; s < this.selectors.length; s++) {
+ for (var c = 0; c < context.length; c++) {
+ paths.push(context[c].concat([this.selectors[s]]));
+ }
+ }
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ if (this.elements[0].value === other.elements[0].value) {
+ return true;
+ } else {
+ return false;
+ }
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { message: "variable " + name + " is undefined",
+ index: this.index };
+ }
+ }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+require('less/tree').jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:' ||
+ location.protocol === 'chrome:' ||
+ location.protocol === 'chrome-extension:' ||
+ location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (root, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (root, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+ styles[i].type = 'text/css';
+ styles[i].innerHTML = tree.toCSS();
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^(https?|file):/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ css.media = sheet.media || 'screen';
+ css.id = id;
+ document.getElementsByTagName('head')[0].appendChild(css);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? false : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol) {
+ if (xhr.status === 0) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+
+ var template = ['<ul>',
+ '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+ '<li><label>[0]</label><pre>{current}</pre></li>',
+ '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+ '</ul>'].join('\n');
+
+ var elem = document.createElement('div'), timer, content;
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p><a href="' + href + '">' + href + "</a> ";
+
+ if (e.extract) {
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ template.replace(/\[(-?\d)\]/g, function (_, i) {
+ return (parseInt(e.line) + parseInt(i)) || '';
+ }).replace(/\{(\d)\}/g, function (_, i) {
+ return e.extract[parseInt(i)] || '';
+ }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+ e.extract[1].slice(e.column) + '</span>');
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #ee4444;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.ctx {',
+ 'color: #dd4444;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless111minjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.1.min.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.1.min.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.1.min.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.1
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+//
+// LESS - Leaner CSS v1.1.1
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function v(a,b){var c="less-error-message:"+p(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p><a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+":</p>"+e.replace(/\[(-?\d)\]/g,function(b,c){return parseInt(a.line)+parseInt(c)||""}).replace(/\{(\d)\}/g,function(b,c){return a.extract[parseInt(c)]||"&q
uot;}).replace(/\{current\}/,a.extract[1].slice(0,a.column)+'<span class="error">'+a.extract[1].slice(a.column)+"</span>")),f.innerHTML=h,q([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #ee4444;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.ctx {","color: #dd4444;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","
;color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=setInterval(function(){document.body&&(document.getElementById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}function u(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: &quo
t;+a)}function t(a){return a&&a.parentNode.removeChild(a)}function s(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){u("browser doesn't support AJAX.");return null}}function r(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var f=s(),h=g?!1:d.async;typeof f.overrideMimeType=="function"&&f.overrideMimeType("text/css"),f.open("GET",a,h),f.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),f.send(null),g?f.status===0?c(f.responseText):e(f.status,a):h?f.onreadystatechange=function(){f.readyState==4&&i(f,c,e)}:i(f,c,e)}function q(a,b,c){var d,e=b.href?b.href.replace(/\?.*$/,""):"",f="less:"+(b.title||p(e));(d=document.getElementById(f))===null&
&(d=document.createElement("style"),d.type="text/css",d.media=b.media||"screen",d.id=f,document.getElementsByTagName("head")[0].appendChild(d));if(d.styleSheet)try{d.styleSheet.cssText=a}catch(g){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(a){d.childNodes.length>0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&h&&(u("saving "+e+" to cache."),h.setItem(e,a),h.setItem(e+":timestamp",c))}function p(a){return a.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\?.*$/,"").replace(/\.[^\.\/]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function o(b,c,e,f){var g=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/,""),j=h&&h.getItem(i),k=h&&h.getItem(i+":ti
mestamp"),l={css:j,timestamp:k};/^(https?|file):/.test(i)||(i.charAt(0)=="/"?i=a.location.protocol+"//"+a.location.host+i:i=g.slice(0,g.lastIndexOf("/")+1)+i),r(b.href,b.type,function(a,g){if(!e&&l&&g&&(new Date(g)).valueOf()===(new Date(l.timestamp)).valueOf())q(l.css,b),c(null,b,{local:!0,remaining:f});else try{(new d.Parser({optimization:d.optimization,paths:[i.replace(/[\w\.-]+$/,"")],mime:b.type})).parse(a,function(a,d){if(a)return v(a,i);try{c(d,b,{local:!1,lastModified:g,remaining:f}),t(document.getElementById("less-error-message:"+p(i)))}catch(a){v(a,i)}})}catch(h){v(h,i)}},function(a,b){throw new Error("Couldn't load "+b+" ("+a+")")})}function n(a,b){for(var c=0;c<d.sheets.length;c++)o(d.sheets[c],a,b,d.sheets.length-(c+1))}function m(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(k)&&(new d.Parser).p
arse(a[b].innerHTML||"",function(c,d){a[b].type="text/css",a[b].innerHTML=d.toCSS()})}function c(b){return a.less[b.split("/")[1]]}Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d<c;d++)d in this&&a.call(b,this[d],d,this)}),Array.prototype.map||(Array.prototype.map=function(a){var b=this.length>>>0,c=Array(b),d=arguments[1];for(var e=0;e<b;e++)e in this&&(c[e]=a.call(d,this[e],e,this));return c}),Array.prototype.filter||(Array.prototype.filter=function(a){var b=[],c=arguments[1];for(var d=0;d<this.length;d++)a.call(c,this[d])&&b.push(this[d]);return b}),Array.prototype.reduce||(Array.prototype.reduce=function(a){var b=this.length>>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.leng
th>=2)var d=arguments[1];else for(;;){if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}for(;c<b;c++)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){var b=this.length,c=arguments[1]||0;if(!b)return-1;if(c>=b)return-1;c<0&&(c+=b);for(;c<b;c++){if(!Object.prototype.hasOwnProperty.call(this,c))continue;if(a===this[c])return c}return-1}),Object.keys||(Object.keys=function(a){var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}),String.prototype.trim||(String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")});var d,e;typeof a=="undefined"?(d=exports,e=c("less/tree")):(typeof a.less=="undefined"&&(a.less={}),d=a.less,e=a.less.tree={}),d.Parser=function(a){function t(a){return typeof a=="string"?b.charAt(c)===a:a.test(j[f])?!0:!1
}function s(a){var d,e,g,h,i,m,n,o;if(a instanceof Function)return a.call(l.parsers);if(typeof a=="string")d=b.charAt(c)===a?a:null,g=1,r();else{r();if(d=a.exec(j[f]))g=d[0].length;else return null}if(d){o=c+=g,m=c+j[f].length-g;while(c<m){h=b.charCodeAt(c);if(h!==32&&h!==10&&h!==9)break;c++}j[f]=j[f].slice(g+(c-o)),k=c,j[f].length===0&&f<j.length-1&&f++;return typeof d=="string"?d:d.length===1?d[0]:d}}function r(){c>k&&(j[f]=j[f].slice(c-k),k=c)}function q(){j[f]=g,c=h,k=c}function p(){g=j[f],h=c,k=c}var b,c,f,g,h,i,j,k,l,m=this,n=function(){},o=this.imports={paths:a&&a.paths||[],queue:[],files:{},mime:a&&a.mime,push:function(b,c){var e=this;this.queue.push(b),d.Parser.importer(b,this.paths,function(a){e.queue.splice(e.queue.indexOf(b),1),e.files[b]=a,c(a),e.queue.length===0&&n()},a)}};this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.fi
lename=this.env.filename||null;return l={imports:o,parse:function(d,g){var h,l,m,o,p,q,r=[],t,u=null;c=f=k=i=0,j=[],b=d.replace(/\r\n/g,"\n"),j=function(c){var d=0,e=/[^"'`\{\}\/\(\)]+/g,f=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,g=0,h,i=c[0],j,k;for(var l=0,m,n;l<b.length;l++){e.lastIndex=l,(h=e.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0])),m=b.charAt(l),f.lastIndex=l,!k&&!j&&m==="/"&&(n=b.charAt(l+1),(n==="/"||n==="*")&&(h=f.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0]),m=b.charAt(l)));if(m==="{"&&!k&&!j)g++,i.push(m);else if(m==="}"&&!k&&!j)g--,i.push(m),c[++d]=i=[];else if(m==="("&&!k&&!j)i.push(m),j=!0;else if(m===")"&&!k&&j)i.push(m),j=!1;else{if(m==='"'||m==="'"||m==="`")k?k=k===m?!1:k:k=m;i.push(m)}}if(g>0)throw{type:"S
yntax",message:"Missing closing `}`",filename:a.filename};return c.map(function(a){return a.join("")})}([[]]),h=new e.Ruleset([],s(this.parsers.primary)),h.root=!0,h.toCSS=function(c){var d,f,g;return function(g,h){function n(a){return a?(b.slice(0,a).match(/\n/g)||"").length:null}var i=[];g=g||{},typeof h=="object"&&!Array.isArray(h)&&(h=Object.keys(h).map(function(a){var b=h[a];b instanceof e.Value||(b instanceof e.Expression||(b=new e.Expression([b])),b=new e.Value([b]));return new e.Rule("@"+a,b,!1,0)}),i=[new e.Ruleset(null,h)]);try{var j=c.call(this,{frames:i}).toCSS([],{compress:g.compress||!1})}catch(k){f=b.split("\n"),d=n(k.index);for(var l=k.index,m=-1;l>=0&&b.charAt(l)!=="\n";l--)m++;throw{type:k.type,message:k.message,filename:a.filename,index:k.index,line:typeof d=="number"?d+1:null,callLine:k.call&&n(k.call)+1,callExtract:f[n(k.call)],stack:k.stack,co
lumn:m,extract:[f[d-1],f[d],f[d+1]]}}return g.compress?j.replace(/(\s)+/g,"$1"):j}}(h.eval);if(c<b.length-1){c=i,q=b.split("\n"),p=(b.slice(0,c).match(/\n/g)||"").length+1;for(var v=c,w=-1;v>=0&&b.charAt(v)!=="\n";v--)w++;u={name:"ParseError",message:"Syntax Error on line "+p,index:c,filename:a.filename,line:p,column:w,extract:[q[p-2],q[p-1],q[p]]}}this.imports.queue.length>0?n=function(){g(u,h)}:g(u,h)},parsers:{primary:function(){var a,b=[];while((a=s(this.mixin.definition)||s(this.rule)||s(this.ruleset)||s(this.mixin.call)||s(this.comment)||s(this.directive))||s(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(b.charAt(c)==="/"){if(b.charAt(c+1)==="/")return new e.Comment(s(/^\/\/.*/),!0);if(a=s(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new e.Comment(a)}},entities:{quoted:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)==='&q
uot;'||b.charAt(d)==="'"){f&&s("~");if(a=s(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new e.Quoted(a[0],a[1]||a[2],f)}},keyword:function(){var a;if(a=s(/^[A-Za-z-]+/))return new e.Keyword(a)},call:function(){var a,b;if(!!(a=/^([\w-]+|%)\(/.exec(j[f]))){a=a[1].toLowerCase();if(a==="url")return null;c+=a.length;if(a==="alpha")return s(this.alpha);s("("),b=s(this.entities.arguments);if(!s(")"))return;if(a)return new e.Call(a,b)}},arguments:function(){var a=[],b;while(b=s(this.expression)){a.push(b);if(!s(","))break}return a},literal:function(){return s(this.entities.dimension)||s(this.entities.color)||s(this.entities.quoted)},url:function(){var a;if(b.charAt(c)==="u"&&!!s(/^url\(/)){a=s(this.entities.quoted)||s(this.entities.variable)||s(this.entities.dataURI)||s(/^[-\w%@$\/.&=:;#+?~]+/)||"";if(!s(")"))throw new Error("missing closi
ng ) for url()");return new e.URL(a.value||a.data||a instanceof e.Variable?a:new e.Anonymous(a),o.paths)}},dataURI:function(){var a;if(s(/^data:/)){a={},a.mime=s(/^[^\/]+\/[^,;)]+/)||"",a.charset=s(/^;\s*charset=[^,;)]+/)||"",a.base64=s(/^;\s*base64/)||"",a.data=s(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var a,d=c;if(b.charAt(c)==="@"&&(a=s(/^@@?[\w-]+/)))return new e.Variable(a,d)},color:function(){var a;if(b.charAt(c)==="#"&&(a=s(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new e.Color(a[1])},dimension:function(){var a,d=b.charCodeAt(c);if(!(d>57||d<45||d===47))if(a=s(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new e.Dimension(a[1],a[2])},javascript:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)==="`"){f&&s("~");if(a=s(/^`([^`]*)`/))return new e.JavaScript(a[1],c,f)}}},variable:function(){var a
;if(b.charAt(c)==="@"&&(a=s(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!!t(/^[@\w.%-]+\/[@\w.-]+/)&&(a=s(this.entity))&&s("/")&&(b=s(this.entity)))return new e.Shorthand(a,b)},mixin:{call:function(){var a=[],d,f,g,h=c,i=b.charAt(c);if(i==="."||i==="#"){while(d=s(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))a.push(new e.Element(f,d)),f=s(">");s("(")&&(g=s(this.entities.arguments))&&s(")");if(a.length>0&&(s(";")||t("}")))return new e.mixin.Call(a,g,h)}},definition:function(){var a,d=[],f,g,h,i;if(!(b.charAt(c)!=="."&&b.charAt(c)!=="#"||t(/^[^{]*(;|})/)))if(f=s(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=f[1];while(h=s(this.entities.variable)||s(this.entities.literal)||s(this.entities.keyword)){if(h instanceof e.Variable)if(s(":"))if(i=s(this.e
xpression))d.push({name:h.name,value:i});else throw new Error("Expected value");else d.push({name:h.name});else d.push({value:h});if(!s(","))break}if(!s(")"))throw new Error("Expected )");g=s(this.block);if(g)return new e.mixin.Definition(a,d,g)}}},entity:function(){return s(this.entities.literal)||s(this.entities.variable)||s(this.entities.url)||s(this.entities.call)||s(this.entities.keyword)||s(this.entities.javascript)||s(this.comment)},end:function(){return s(";")||t("}")},alpha:function(){var a;if(!!s(/^opacity=/i))if(a=s(/^\d+/)||s(this.entities.variable)){if(!s(")"))throw new Error("missing closing ) for alpha()");return new e.Alpha(a)}},element:function(){var a,b,c;c=s(this.combinator),a=s(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||s("*")||s(this.attribute)||s(/^\([^)@]+\)/);if(a)return new e.Element(c,a)},combinator:function(){var a,d=b.charAt(c);if(d===">
;"||d==="&"||d==="+"||d==="~"){c++;while(b.charAt(c)===" ")c++;return new e.Combinator(d)}if(d===":"&&b.charAt(c+1)===":"){c+=2;while(b.charAt(c)===" ")c++;return new e.Combinator("::")}return b.charAt(c-1)===" "?new e.Combinator(" "):new e.Combinator(null)},selector:function(){var a,d,f=[],g,h;while(d=s(this.element)){g=b.charAt(c),f.push(d);if(g==="{"||g==="}"||g===";"||g===",")break}if(f.length>0)return new e.Selector(f)},tag:function(){return s(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||s("*")},attribute:function(){var a="",b,c,d;if(!!s("[")){if(b=s(/^[a-zA-Z-]+/)||s(this.entities.quoted))(d=s(/^[|~*$^]?=/))&&(c=s(this.entities.quoted)||s(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!s("]"))return;if(a)return"["+a+"]"}},block:function(){var a;if(s
("{")&&(a=s(this.primary))&&s("}"))return a},ruleset:function(){var a=[],b,d,g;p();if(g=/^([.#: \w-]+)[\s\n]*\{/.exec(j[f]))c+=g[0].length-1,a=[new e.Selector([new e.Element(null,g[1])])];else while(b=s(this.selector)){a.push(b),s(this.comment);if(!s(","))break;s(this.comment)}if(a.length>0&&(d=s(this.block)))return new e.Ruleset(a,d);i=c,q()},rule:function(){var a,d,g=b.charAt(c),k,l;p();if(g!=="."&&g!=="#"&&g!=="&")if(a=s(this.variable)||s(this.property)){a.charAt(0)!="@"&&(l=/^([^@+\/'"*`(;{}-]*);/.exec(j[f]))?(c+=l[0].length-1,d=new e.Anonymous(l[1])):a==="font"?d=s(this.font):d=s(this.value),k=s(this.important);if(d&&s(this.end))return new e.Rule(a,d,k,h);i=c,q()}},"import":function(){var a;if(s(/^@import\s+/)&&(a=s(this.entities.quoted)||s(this.entities.url))&&s(";"))return new e.Import(a,o)},dir
ective:function(){var a,d,f,g;if(b.charAt(c)==="@"){if(d=s(this["import"]))return d;if(a=s(/^@media|@page|@-[-a-z]+/)){g=(s(/^[^{]+/)||"").trim();if(f=s(this.block))return new e.Directive(a+" "+g,f)}else if(a=s(/^@[-a-z]+/))if(a==="@font-face"){if(f=s(this.block))return new e.Directive(a,f)}else if((d=s(this.entity))&&s(";"))return new e.Directive(a,d)}},font:function(){var a=[],b=[],c,d,f,g;while(g=s(this.shorthand)||s(this.entity))b.push(g);a.push(new e.Expression(b));if(s(","))while(g=s(this.expression)){a.push(g);if(!s(","))break}return new e.Value(a)},value:function(){var a,b=[],c;while(a=s(this.expression)){b.push(a);if(!s(","))break}if(b.length>0)return new e.Value(b)},important:function(){if(b.charAt(c)==="!")return s(/^! *important/)},sub:function(){var a;if(s("(")&&(a=s(this.expression))&&s(")"))return a},multiplication:function
(){var a,b,c,d;if(a=s(this.operand)){while((c=s("/")||s("*"))&&(b=s(this.operand)))d=new e.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,d,f,g;if(a=s(this.multiplication)){while((f=s(/^[-+]\s+/)||b.charAt(c-1)!=" "&&(s("+")||s("-")))&&(d=s(this.multiplication)))g=new e.Operation(f,[g||a,d]);return g||a}},operand:function(){var a,d=b.charAt(c+1);b.charAt(c)==="-"&&(d==="@"||d==="(")&&(a=s("-"));var f=s(this.sub)||s(this.entities.dimension)||s(this.entities.color)||s(this.entities.variable)||s(this.entities.call);return a?new e.Operation("*",[new e.Dimension(-1),f]):f},expression:function(){var a,b,c=[],d;while(a=s(this.addition)||s(this.entity))c.push(a);if(c.length>0)return new e.Expression(c)},property:function(){var a;if(a=s(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}},typeof a!="undefined"&&(d.Parser.importe
r=function(a,b,c,d){a.charAt(0)!=="/"&&b.length>0&&(a=b[0]+a),o({href:a,title:a,type:d.mime},c,!0)}),function(a){function d(a){return Math.min(1,Math.max(0,a))}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){a=a<0?a+1:a>1?a-1:a;return a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(M
ath.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();e.s+=c.value/100,e.s=d(e.s);return b(e)},desaturate:function(a,c){var e=a.toHSL();e.s-=c.value/100,e.s=d(e.s);return b(e)},lighten:function(a,c){var e=a.toHSL();e.l+=c.value/100,e.l=d(e.l);return b(e)},darken:function(a,c){var e=a.toHSL();e.l-=c.value/100,e.l=d(e.l);return b(e)},fadein:function(a,c){var e=a.toHSL();e.a+=c.value/100,e.a=d(e.a);return b(e)},fadeout:function(a,c){var e=a.toHSL();e.a-=c.value/100,e.a=d(e.a);return b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;d.h=e<0?360+e:e;return b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb
[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e<c.length;e++)d=d.replace(/%[sda]/i,function(a){var b=a.match(/s/i)?c[e].value:c[e].toCSS();return a.match(/[A-Z]$/)?encodeURIComponent(b):b});d=d.replace(/%%/g,"%");return new a.Quoted('"'+d+'"',d)},round:function(b){if(b instanceof a.Dimension)return new a.Dimension(Math.round(c(b)),b.unit);if(typeof b=="number")return Math.round(b);throw{error:"RuntimeError",message:"math functions take numbers a
s parameters"}}}}(c("less/tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(){return this}}}(c("less/tree")),function(a){a.Anonymous=function(a){this.value=a.value||a},a.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this}}}(c("less/tree")),function(a){a.Call=function(a,b){this.name=a,this.args=b},a.Call.prototype={eval:function(b){var c=this.args.map(function(a){return a.eval(b)});return this.name in a.functions?a.functions[this.name].apply(a.functions,c):new a.Anonymous(this.name+"("+c.map(function(a){return a.toCSS()}).join(", ")+")")},toCSS:function(a){return this.eval(a).toCSS()}}}(c("less/tree")),function(a){a.Color=function(a,b){Array.isArray(a)?this.rgb=a:a.length==6?this.rgb=a.match(/.{2}/g).map(function(a){return parse
Int(a,16)}):a.length==8?(this.alpha=parseInt(a.substring(0,2),16)/255,this.rgb=a.substr(2).match(/.{2}/g).map(function(a){return parseInt(a,16)})):this.rgb=a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha=typeof b=="number"?b:1},a.Color.prototype={eval:function(){return this},toCSS:function(){return this.alpha<1?"rgba("+this.rgb.map(function(a){return Math.round(a)}).concat(this.alpha).join(", ")+")":"#"+this.rgb.map(function(a){a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16);return a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);swi
tch(e){case a:g=(b-c)/j+(b<c?6:0);break;case b:g=(c-a)/j+2;break;case c:g=(a-b)/j+4}g/=6}return{h:g*360,s:h,l:i,a:d}}}}(c("less/tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("less/tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)}}}(c("less/tree")),function(a){a.Directive=function(b,c){this.name=b,Array.isArray(c)?this.ruleset=new a.Ruleset([],c):this.value=c},a.Directive.prototype={toCSS:function(a,b){if(this.ruleset){this.ruleset.root=!0;return this.name+(b.compress?"{":" {\n "
;)+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n ")+(b.compress?"}":"\n}\n")}return this.name+" "+this.value.toCSS()+";\n"},eval:function(a){a.frames.unshift(this),this.ruleset=this.ruleset&&this.ruleset.eval(a),a.frames.shift();return this},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(c("less/tree")),function(a){a.Element=function(b,c){this.combinator=b instanceof a.Combinator?b:new a.Combinator(b),this.value=c.trim()},a.Element.prototype.toCSS=function(a){return this.combinator.toCSS(a||{})+this.value},a.Combinator=function(a){a===" "?this.value=" ":this.value=a?a.trim():""},a.Combinator.prototype.toCSS=function(a){return{"":""," ":" ","&"
:"",":":" :","::":"::","+":a.compress?"+":" + ","~":a.compress?"~":" ~ ",">":a.compress?">":" > "}[this.value]}}(c("less/tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(" ")}}}(c("less/tree")),function(a){a.Import=function(b,c){var d=this;this._path=b,b instanceof a.Quoted?this.path=/\.(le?|c)ss$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value||b.value,this.css=/css$/.test(this.path),this.css||c.push(this.path,function(a){if(!a)throw new Error("Error parsing "+d.path);d.root=a})},a.Import.prototype={toCSS
:function(){return this.css?"@import "+this._path.toCSS()+";\n":""},eval:function(b){var c;if(this.css)return this;c=new a.Ruleset(null,this.root.rules.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));return c.rules}}}(c("less/tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify((new a.Variable("@"+e,d.index)).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: `"+f+"`",index:this.index}}for(var h in b.frames[0].variables())e[h.slice(1)]={value:b.frames[0].variables()[h].value,toJS:function(){return this.value.eval(b).toCSS()}};try{c=f.call(e)}catch(g){throw{message:&quo
t;JavaScript evaluation error: '"+g.name+": "+g.message+"'",index:this.index}}return typeof c=="string"?new a.Quoted('"'+c+'"',c,this.escaped,this.index):Array.isArray(c)?new a.Anonymous(c.join(", ")):new a.Anonymous(c)}}}(c("less/tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value}}}(c("less/tree")),function(a){a.mixin={},a.mixin.Call=function(b,c,d){this.selector=new a.Selector(b),this.arguments=c,this.index=d},a.mixin.Call.prototype={eval:function(a){var b,c=[],d=!1;for(var e=0;e<a.frames.length;e++)if((b=a.frames[e].find(this.selector)).length>0){for(var f=0;f<b.length;f++)if(b[f].match(this.arguments,a))try{Array.prototype.push.apply(c,b[f].eval(a,this.arguments).rules),d=!0}catch(g){throw{message:g.message,index:g.index,stack:g.stack,call:this.index}}if(d)return c;throw{message:"No matching definition
was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(a){return a.toCSS()}).join(", ")+")`",index:this.index}}throw{message:this.selector.toCSS().trim()+" is undefined",index:this.index}}},a.mixin.Definition=function(b,c,d){this.name=b,this.selectors=[new a.Selector([new a.Element(null,b)])],this.params=c,this.arity=c.length,this.rules=d,this._lookups={},this.required=c.reduce(function(a,b){return!b.name||b.name&&!b.value?a+1:a},0),this.parent=a.Ruleset.prototype,this.frames=[]},a.mixin.Definition.prototype={toCSS:function(){return""},variable:function(a){return this.parent.variable.call(this,a)},variables:function(){return this.parent.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},eval:function(b,c){var d=new a.Ruleset(null,[]),e,f=[];for(var g=0,h;g<this.params.length;g++)if(this.params[g].name)
if(h=c&&c[g]||this.params[g].value)d.rules.unshift(new a.Rule(this.params[g].name,h.eval(b)));else throw{message:"wrong number of arguments for "+this.name+" ("+c.length+" for "+this.arity+")"};for(var g=0;g<Math.max(this.params.length,c&&c.length);g++)f.push(c[g]||this.params[g].value);d.rules.unshift(new a.Rule("@arguments",(new a.Expression(f)).eval(b)));return(new a.Ruleset(null,this.rules.slice(0))).eval({frames:[this,d].concat(this.frames,b.frames)})},match:function(a,b){var c=a&&a.length||0,d;if(c<this.required)return!1;if(this.required>0&&c>this.params.length)return!1;d=Math.min(c,this.arity);for(var e=0;e<d;e++)if(!this.params[e].name&&a[e].eval(b).toCSS()!=this.params[e].value.eval(b).toCSS())return!1;return!0}}}(c("less/tree")),function(a){a.Operation=function(a,b){this.op=a.trim(),this.operands=b},a.Operation.prototype.eval=function(b){var c=this.operands[0]
.eval(b),d=this.operands[1].eval(b),e;if(c instanceof a.Dimension&&d instanceof a.Color)if(this.op==="*"||this.op==="+")e=d,d=c,c=e;else throw{name:"OperationError",message:"Can't substract or divide a color from a number"};return c.operate(this.op,d)},a.operate=function(a,b,c){switch(a){case"+":return b+c;case"-":return b-c;case"*":return b*c;case"/":return b/c}}}(c("less/tree")),function(a){a.Quoted=function(a,b,c,d){this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d},a.Quoted.prototype={toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(b){var c=this;this.value=this.value.replace(/`([^`]+)`/g,function(d,e){return(new a.JavaScript(e,c.index,!0)).eval(b).value}).replace(/@\{([\w-]+)\}/g,function(d,e){return(new a.Variable("@"+e,c.index)).eval(b).value});return this}}}(c("less/tree")),function(a)
{a.Rule=function(b,c,d,e){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.index=e,b.charAt(0)==="@"?this.variable=!0:this.variable=!1},a.Rule.prototype.toCSS=function(a){return this.variable?"":this.name+(a.compress?":":": ")+this.value.toCSS(a)+this.important+";"},a.Rule.prototype.eval=function(b){return new a.Rule(this.name,this.value.eval(b),this.important,this.index)},a.Shorthand=function(a,b){this.a=a,this.b=b},a.Shorthand.prototype={toCSS:function(a){return this.a.toCSS(a)+"/"+this.b.toCSS(a)},eval:function(){return this}}}(c("less/tree")),function(a){a.Ruleset=function(a,b){this.selectors=a,this.rules=b,this._lookups={}},a.Ruleset.prototype={eval:function(b){var c=new a.Ruleset(this.selectors,this.rules.slice(0));c.root=this.root,b.frames.unshift(c);if(c.root)for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Ar
ray.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Definition&&(c.rules[d].frames=b.frames.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Call&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0,e;d<c.rules.length;d++)e=c.rules[d],e instanceof a.mixin.Definition||(c.rules[d]=e.eval?e.eval(b):e);b.frames.shift();return c},match:function(a){return!a||a.length===0},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(b,c){c instanceof a.Rule&&c.variable===!0&&(b[c.name]=c);return b},{})},variable:function(a){return this.variables()[a]},rulesets:function(){return this._rulesets?this._rulesets:this._rulesets=this.rules.filter(function(b){return b instanceof a.Ruleset||b instanceof a.mixin.Definition})},find:function(b,c){c=c||this;var d=[],e,f,g=b.toCSS();if(g in
this._lookups)return this._lookups[g];this.rulesets().forEach(function(e){if(e!==c)for(var g=0;g<e.selectors.length;g++)if(f=b.match(e.selectors[g])){b.elements.length>1?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}});return this._lookups[g]=d},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;if(!this.root)if(b.length===0)g=this.selectors.map(function(a){return[a]});else for(var j=0;j<this.selectors.length;j++)for(var k=0;k<b.length;k++)g.push(b[k].concat([this.selectors[j]]));for(var l=0;l<this.rules.length;l++)i=this.rules[l],i.rules||i instanceof a.Directive?f.push(i.toCSS(g,c)):i instanceof a.Comment?i.silent||(this.root?f.push(i.toCSS(c)):e.push(i.toCSS(c))):i.toCSS&&!i.variable?e.push(i.toCSS(c)):i.value&&!i.variable&&e.push(i.value.toString());f=f.join(""),this.root?d.push(e.join(c.compress?"":"\n")):e.length>0&&(h=g.map(function(a){return a.map(functi
on(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":g.length>3?",\n":", "),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f);return d.join("")+(c.compress?"\n":"")}}}(c("less/tree")),function(a){a.Selector=function(a){this.elements=a,this.elements[0].combinator.value===""&&(this.elements[0].combinator.value=" ")},a.Selector.prototype.match=function(a){return this.elements[0].value===a.elements[0].value?!0:!1},a.Selector.prototype.toCSS=function(a){if(this._css)return this._css;return this._css=this.elements.map(function(b){return typeof b=="string"?" "+b.trim():b.toCSS(a)}).join("")}}(c("less/tree")),function(b){b.URL=function(b,c){b.data?this.attrs=b:(!/^(?:https?:\/|file:\/|data:\/)?\//.test(b.value)&&c.
length>0&&typeof a!="undefined"&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("less/tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("less/tree")),function(a){a.Variable=function(a,b){this.name=a,this.index=b},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e=&
quot;@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{message:"variable "+e+" is undefined",index:this.index}}}}(c("less/tree"
+)),c("less/tree").find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null},c("less/tree").jsify=function(a){return Array.isArray(a.value)&&a.value.length>1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)};var g=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||g?"development":"production"),d.async=!1,d.poll=d.poll||(g?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchM
ode&&n(function(a,b,c){a&&q(a.toCSS(),b,c.lastModified)})},d.poll)):d.optimization=3;var h;try{h=typeof a.localStorage=="undefined"?null:a.localStorage}catch(i){h=null}var j=document.getElementsByTagName("link"),k=/^text\/(x-)?less$/;d.sheets=[];for(var l=0;l<j.length;l++)(j[l].rel==="stylesheet/less"||j[l].rel.match(/stylesheet/)&&j[l].type.match(k))&&d.sheets.push(j[l]);d.refresh=function(a){var b,c;b=c=new Date,n(function(a,d,e){e.local?u("loading "+d.href+" from cache."):(u("parsed "+d.href+" successfully."),q(a.toCSS(),d,e.lastModified)),u("css for "+d.href+" generated in "+(new Date-c)+"ms"),e.remaining===0&&u("css generated in "+(new Date-b)+"ms"),c=new Date},a),m()},d.refreshStyles=m,d.refresh(d.env==="development")})(window)
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless112js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.2.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.2.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.2.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2712 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.2
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+ less = exports,
+ tree = require('less/tree');
+} else {
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ mime: env && env.mime, // MIME type of .less files
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (root) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+
+ callback(root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ chunks = [];
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam,
+ inString;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = i;
+
+ if (!inString && !inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ if (c === '{' && !inString && !inParam) { level ++;
+ chunk.push(c);
+ } else if (c === '}' && !inString && !inParam) { level --;
+ chunk.push(c);
+ chunks[++j] = chunk = [];
+ } else if (c === '(' && !inString && !inParam) {
+ chunk.push(c);
+ inParam = true;
+ } else if (c === ')' && !inString && inParam) {
+ chunk.push(c);
+ inParam = false;
+ } else {
+ if (c === '"' || c === "'" || c === '`') {
+ if (! inString) {
+ inString = c;
+ } else {
+ inString = inString === c ? false : inString;
+ }
+ }
+ chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ throw {
+ type: 'Syntax',
+ message: "Missing closing `}`",
+ filename: env.filename
+ };
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [];
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ lines = input.split('\n');
+ line = getLine(e.index);
+
+ for (var n = e.index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ throw {
+ type: e.type,
+ message: e.message,
+ filename: env.filename,
+ index: e.index,
+ line: typeof(line) === 'number' ? line + 1 : null,
+ callLine: e.call && (getLine(e.call) + 1),
+ callExtract: lines[getLine(e.call)],
+ stack: e.stack,
+ column: column,
+ extract: [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ]
+ };
+ }
+ if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+
+ function getLine(index) {
+ return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ name: "ParseError",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+ if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args;
+
+ if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+ if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value;
+
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ while (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ if (value = $(this.expression)) {
+ params.push({ name: param.name, value: value });
+ } else {
+ throw new(Error)("Expected value");
+ }
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ if (! $(',')) { break }
+ }
+ if (! $(')')) throw new(Error)("Expected )");
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset);
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c;
+
+ c = $(this.combinator);
+ e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+ if (e) { return new(tree.Element)(c, e) }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '&' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === ':' && input.charAt(i + 1) === ':') {
+ i += 2;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)('::');
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ if (match = /^([.#: \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+ i += match[0].length - 1;
+ selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+ } else {
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url)) &&
+ $(';')) {
+ return new(tree.Import)(path, imports);
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import'])) {
+ return value;
+ } else if (name = $(/^@media|@page|@-[-a-z]+/)) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (typeof(window) !== 'undefined') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (path.charAt(0) !== '/' && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math.round(number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math.round(n);
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "math functions take numbers as parameters"
+ };
+ }
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args) {
+ this.name = name;
+ this.args = args;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ return tree.functions[this.name].apply(tree.functions, args);
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else if (rgb.length == 8) {
+ this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
+ this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+ this.name = name;
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+ this.value = value.trim();
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ ':' : ' :',
+ '::': '::',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(' ');
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+ var that = this;
+
+ this._path = path;
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (root) {
+ if (! root) {
+ throw new(Error)("Error parsing " + that.path);
+ }
+ that.root = root;
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function () {
+ if (this.css) {
+ return "@import " + this._path.toCSS() + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset;
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return ruleset.rules;
+ }
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index };
+ }
+ }
+ }
+ throw { message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ eval: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+ for (var i = 0, val; i < this.params.length; i++) {
+ if (this.params[i].name) {
+ if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+ } else {
+ throw { message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len;
+
+ if (argsLength < this.required) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return v.value || v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + ";";
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+ ruleset.root = this.root;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > 1) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ for (var s = 0; s < this.selectors.length; s++) {
+ for (var c = 0; c < context.length; c++) {
+ paths.push(context[c].concat([this.selectors[s]]));
+ }
+ }
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ if (this.elements[0].value === other.elements[0].value) {
+ return true;
+ } else {
+ return false;
+ }
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { message: "variable " + name + " is undefined",
+ index: this.index };
+ }
+ }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+require('less/tree').jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:' ||
+ location.protocol === 'chrome:' ||
+ location.protocol === 'chrome-extension:' ||
+ location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (root, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (root, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+ styles[i].type = 'text/css';
+ styles[i].innerHTML = tree.toCSS();
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^(https?|file):/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ css.media = sheet.media || 'screen';
+ css.id = id;
+ document.getElementsByTagName('head')[0].appendChild(css);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? false : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol) {
+ if (xhr.status === 0) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+
+ var template = ['<ul>',
+ '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+ '<li><label>[0]</label><pre>{current}</pre></li>',
+ '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+ '</ul>'].join('\n');
+
+ var elem = document.createElement('div'), timer, content;
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p><a href="' + href + '">' + href + "</a> ";
+
+ if (e.extract) {
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ template.replace(/\[(-?\d)\]/g, function (_, i) {
+ return (parseInt(e.line) + parseInt(i)) || '';
+ }).replace(/\{(\d)\}/g, function (_, i) {
+ return e.extract[parseInt(i)] || '';
+ }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+ e.extract[1].slice(e.column) + '</span>');
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #ee4444;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.ctx {',
+ 'color: #dd4444;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless112minjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.2.min.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.2.min.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.2.min.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.2
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+//
+// LESS - Leaner CSS v1.1.2
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function v(a,b){var c="less-error-message:"+p(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p><a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+":</p>"+e.replace(/\[(-?\d)\]/g,function(b,c){return parseInt(a.line)+parseInt(c)||""}).replace(/\{(\d)\}/g,function(b,c){return a.extract[parseInt(c)]||"&q
uot;}).replace(/\{current\}/,a.extract[1].slice(0,a.column)+'<span class="error">'+a.extract[1].slice(a.column)+"</span>")),f.innerHTML=h,q([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #ee4444;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.ctx {","color: #dd4444;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","
;color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=setInterval(function(){document.body&&(document.getElementById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}function u(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: &quo
t;+a)}function t(a){return a&&a.parentNode.removeChild(a)}function s(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){u("browser doesn't support AJAX.");return null}}function r(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var f=s(),h=g?!1:d.async;typeof f.overrideMimeType=="function"&&f.overrideMimeType("text/css"),f.open("GET",a,h),f.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),f.send(null),g?f.status===0?c(f.responseText):e(f.status,a):h?f.onreadystatechange=function(){f.readyState==4&&i(f,c,e)}:i(f,c,e)}function q(a,b,c){var d,e=b.href?b.href.replace(/\?.*$/,""):"",f="less:"+(b.title||p(e));(d=document.getElementById(f))===null&
&(d=document.createElement("style"),d.type="text/css",d.media=b.media||"screen",d.id=f,document.getElementsByTagName("head")[0].appendChild(d));if(d.styleSheet)try{d.styleSheet.cssText=a}catch(g){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(a){d.childNodes.length>0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&h&&(u("saving "+e+" to cache."),h.setItem(e,a),h.setItem(e+":timestamp",c))}function p(a){return a.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\?.*$/,"").replace(/\.[^\.\/]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function o(b,c,e,f){var g=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/,""),j=h&&h.getItem(i),k=h&&h.getItem(i+":ti
mestamp"),l={css:j,timestamp:k};/^(https?|file):/.test(i)||(i.charAt(0)=="/"?i=a.location.protocol+"//"+a.location.host+i:i=g.slice(0,g.lastIndexOf("/")+1)+i),r(b.href,b.type,function(a,g){if(!e&&l&&g&&(new Date(g)).valueOf()===(new Date(l.timestamp)).valueOf())q(l.css,b),c(null,b,{local:!0,remaining:f});else try{(new d.Parser({optimization:d.optimization,paths:[i.replace(/[\w\.-]+$/,"")],mime:b.type})).parse(a,function(a,d){if(a)return v(a,i);try{c(d,b,{local:!1,lastModified:g,remaining:f}),t(document.getElementById("less-error-message:"+p(i)))}catch(a){v(a,i)}})}catch(h){v(h,i)}},function(a,b){throw new Error("Couldn't load "+b+" ("+a+")")})}function n(a,b){for(var c=0;c<d.sheets.length;c++)o(d.sheets[c],a,b,d.sheets.length-(c+1))}function m(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(k)&&(new d.Parser).p
arse(a[b].innerHTML||"",function(c,d){a[b].type="text/css",a[b].innerHTML=d.toCSS()})}function c(b){return a.less[b.split("/")[1]]}Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d<c;d++)d in this&&a.call(b,this[d],d,this)}),Array.prototype.map||(Array.prototype.map=function(a){var b=this.length>>>0,c=Array(b),d=arguments[1];for(var e=0;e<b;e++)e in this&&(c[e]=a.call(d,this[e],e,this));return c}),Array.prototype.filter||(Array.prototype.filter=function(a){var b=[],c=arguments[1];for(var d=0;d<this.length;d++)a.call(c,this[d])&&b.push(this[d]);return b}),Array.prototype.reduce||(Array.prototype.reduce=function(a){var b=this.length>>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.leng
th>=2)var d=arguments[1];else for(;;){if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}for(;c<b;c++)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){var b=this.length,c=arguments[1]||0;if(!b)return-1;if(c>=b)return-1;c<0&&(c+=b);for(;c<b;c++){if(!Object.prototype.hasOwnProperty.call(this,c))continue;if(a===this[c])return c}return-1}),Object.keys||(Object.keys=function(a){var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}),String.prototype.trim||(String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")});var d,e;typeof a=="undefined"?(d=exports,e=c("less/tree")):(typeof a.less=="undefined"&&(a.less={}),d=a.less,e=a.less.tree={}),d.Parser=function(a){function t(a){return typeof a=="string"?b.charAt(c)===a:a.test(j[f])?!0:!1
}function s(a){var d,e,g,h,i,m,n,o;if(a instanceof Function)return a.call(l.parsers);if(typeof a=="string")d=b.charAt(c)===a?a:null,g=1,r();else{r();if(d=a.exec(j[f]))g=d[0].length;else return null}if(d){o=c+=g,m=c+j[f].length-g;while(c<m){h=b.charCodeAt(c);if(h!==32&&h!==10&&h!==9)break;c++}j[f]=j[f].slice(g+(c-o)),k=c,j[f].length===0&&f<j.length-1&&f++;return typeof d=="string"?d:d.length===1?d[0]:d}}function r(){c>k&&(j[f]=j[f].slice(c-k),k=c)}function q(){j[f]=g,c=h,k=c}function p(){g=j[f],h=c,k=c}var b,c,f,g,h,i,j,k,l,m=this,n=function(){},o=this.imports={paths:a&&a.paths||[],queue:[],files:{},mime:a&&a.mime,push:function(b,c){var e=this;this.queue.push(b),d.Parser.importer(b,this.paths,function(a){e.queue.splice(e.queue.indexOf(b),1),e.files[b]=a,c(a),e.queue.length===0&&n()},a)}};this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.fi
lename=this.env.filename||null;return l={imports:o,parse:function(d,g){var h,l,m,o,p,q,r=[],t,u=null;c=f=k=i=0,j=[],b=d.replace(/\r\n/g,"\n"),j=function(c){var d=0,e=/[^"'`\{\}\/\(\)]+/g,f=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,g=0,h,i=c[0],j,k;for(var l=0,m,n;l<b.length;l++){e.lastIndex=l,(h=e.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0])),m=b.charAt(l),f.lastIndex=l,!k&&!j&&m==="/"&&(n=b.charAt(l+1),(n==="/"||n==="*")&&(h=f.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0]),m=b.charAt(l)));if(m==="{"&&!k&&!j)g++,i.push(m);else if(m==="}"&&!k&&!j)g--,i.push(m),c[++d]=i=[];else if(m==="("&&!k&&!j)i.push(m),j=!0;else if(m===")"&&!k&&j)i.push(m),j=!1;else{if(m==='"'||m==="'"||m==="`")k?k=k===m?!1:k:k=m;i.push(m)}}if(g>0)throw{type:"S
yntax",message:"Missing closing `}`",filename:a.filename};return c.map(function(a){return a.join("")})}([[]]),h=new e.Ruleset([],s(this.parsers.primary)),h.root=!0,h.toCSS=function(c){var d,f,g;return function(g,h){function n(a){return a?(b.slice(0,a).match(/\n/g)||"").length:null}var i=[];g=g||{},typeof h=="object"&&!Array.isArray(h)&&(h=Object.keys(h).map(function(a){var b=h[a];b instanceof e.Value||(b instanceof e.Expression||(b=new e.Expression([b])),b=new e.Value([b]));return new e.Rule("@"+a,b,!1,0)}),i=[new e.Ruleset(null,h)]);try{var j=c.call(this,{frames:i}).toCSS([],{compress:g.compress||!1})}catch(k){f=b.split("\n"),d=n(k.index);for(var l=k.index,m=-1;l>=0&&b.charAt(l)!=="\n";l--)m++;throw{type:k.type,message:k.message,filename:a.filename,index:k.index,line:typeof d=="number"?d+1:null,callLine:k.call&&n(k.call)+1,callExtract:f[n(k.call)],stack:k.stack,co
lumn:m,extract:[f[d-1],f[d],f[d+1]]}}return g.compress?j.replace(/(\s)+/g,"$1"):j}}(h.eval);if(c<b.length-1){c=i,q=b.split("\n"),p=(b.slice(0,c).match(/\n/g)||"").length+1;for(var v=c,w=-1;v>=0&&b.charAt(v)!=="\n";v--)w++;u={name:"ParseError",message:"Syntax Error on line "+p,index:c,filename:a.filename,line:p,column:w,extract:[q[p-2],q[p-1],q[p]]}}this.imports.queue.length>0?n=function(){g(u,h)}:g(u,h)},parsers:{primary:function(){var a,b=[];while((a=s(this.mixin.definition)||s(this.rule)||s(this.ruleset)||s(this.mixin.call)||s(this.comment)||s(this.directive))||s(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(b.charAt(c)==="/"){if(b.charAt(c+1)==="/")return new e.Comment(s(/^\/\/.*/),!0);if(a=s(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new e.Comment(a)}},entities:{quoted:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)==='&q
uot;'||b.charAt(d)==="'"){f&&s("~");if(a=s(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new e.Quoted(a[0],a[1]||a[2],f)}},keyword:function(){var a;if(a=s(/^[A-Za-z-]+/))return new e.Keyword(a)},call:function(){var a,b;if(!!(a=/^([\w-]+|%)\(/.exec(j[f]))){a=a[1].toLowerCase();if(a==="url")return null;c+=a.length;if(a==="alpha")return s(this.alpha);s("("),b=s(this.entities.arguments);if(!s(")"))return;if(a)return new e.Call(a,b)}},arguments:function(){var a=[],b;while(b=s(this.expression)){a.push(b);if(!s(","))break}return a},literal:function(){return s(this.entities.dimension)||s(this.entities.color)||s(this.entities.quoted)},url:function(){var a;if(b.charAt(c)==="u"&&!!s(/^url\(/)){a=s(this.entities.quoted)||s(this.entities.variable)||s(this.entities.dataURI)||s(/^[-\w%@$\/.&=:;#+?~]+/)||"";if(!s(")"))throw new Error("missing closi
ng ) for url()");return new e.URL(a.value||a.data||a instanceof e.Variable?a:new e.Anonymous(a),o.paths)}},dataURI:function(){var a;if(s(/^data:/)){a={},a.mime=s(/^[^\/]+\/[^,;)]+/)||"",a.charset=s(/^;\s*charset=[^,;)]+/)||"",a.base64=s(/^;\s*base64/)||"",a.data=s(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var a,d=c;if(b.charAt(c)==="@"&&(a=s(/^@@?[\w-]+/)))return new e.Variable(a,d)},color:function(){var a;if(b.charAt(c)==="#"&&(a=s(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new e.Color(a[1])},dimension:function(){var a,d=b.charCodeAt(c);if(!(d>57||d<45||d===47))if(a=s(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new e.Dimension(a[1],a[2])},javascript:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)==="`"){f&&s("~");if(a=s(/^`([^`]*)`/))return new e.JavaScript(a[1],c,f)}}},variable:function(){var a
;if(b.charAt(c)==="@"&&(a=s(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!!t(/^[@\w.%-]+\/[@\w.-]+/)&&(a=s(this.entity))&&s("/")&&(b=s(this.entity)))return new e.Shorthand(a,b)},mixin:{call:function(){var a=[],d,f,g,h=c,i=b.charAt(c);if(i==="."||i==="#"){while(d=s(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))a.push(new e.Element(f,d)),f=s(">");s("(")&&(g=s(this.entities.arguments))&&s(")");if(a.length>0&&(s(";")||t("}")))return new e.mixin.Call(a,g,h)}},definition:function(){var a,d=[],f,g,h,i;if(!(b.charAt(c)!=="."&&b.charAt(c)!=="#"||t(/^[^{]*(;|})/)))if(f=s(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=f[1];while(h=s(this.entities.variable)||s(this.entities.literal)||s(this.entities.keyword)){if(h instanceof e.Variable)if(s(":"))if(i=s(this.e
xpression))d.push({name:h.name,value:i});else throw new Error("Expected value");else d.push({name:h.name});else d.push({value:h});if(!s(","))break}if(!s(")"))throw new Error("Expected )");g=s(this.block);if(g)return new e.mixin.Definition(a,d,g)}}},entity:function(){return s(this.entities.literal)||s(this.entities.variable)||s(this.entities.url)||s(this.entities.call)||s(this.entities.keyword)||s(this.entities.javascript)||s(this.comment)},end:function(){return s(";")||t("}")},alpha:function(){var a;if(!!s(/^opacity=/i))if(a=s(/^\d+/)||s(this.entities.variable)){if(!s(")"))throw new Error("missing closing ) for alpha()");return new e.Alpha(a)}},element:function(){var a,b,c;c=s(this.combinator),a=s(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||s("*")||s(this.attribute)||s(/^\([^)@]+\)/);if(a)return new e.Element(c,a)},combinator:function(){var a,d=b.charAt(c);if(d===">
;"||d==="&"||d==="+"||d==="~"){c++;while(b.charAt(c)===" ")c++;return new e.Combinator(d)}if(d===":"&&b.charAt(c+1)===":"){c+=2;while(b.charAt(c)===" ")c++;return new e.Combinator("::")}return b.charAt(c-1)===" "?new e.Combinator(" "):new e.Combinator(null)},selector:function(){var a,d,f=[],g,h;while(d=s(this.element)){g=b.charAt(c),f.push(d);if(g==="{"||g==="}"||g===";"||g===",")break}if(f.length>0)return new e.Selector(f)},tag:function(){return s(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||s("*")},attribute:function(){var a="",b,c,d;if(!!s("[")){if(b=s(/^[a-zA-Z-]+/)||s(this.entities.quoted))(d=s(/^[|~*$^]?=/))&&(c=s(this.entities.quoted)||s(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!s("]"))return;if(a)return"["+a+"]"}},block:function(){var a;if(s
("{")&&(a=s(this.primary))&&s("}"))return a},ruleset:function(){var a=[],b,d,g;p();if(g=/^([.#: \w-]+)[\s\n]*\{/.exec(j[f]))c+=g[0].length-1,a=[new e.Selector([new e.Element(null,g[1])])];else while(b=s(this.selector)){a.push(b),s(this.comment);if(!s(","))break;s(this.comment)}if(a.length>0&&(d=s(this.block)))return new e.Ruleset(a,d);i=c,q()},rule:function(){var a,d,g=b.charAt(c),k,l;p();if(g!=="."&&g!=="#"&&g!=="&")if(a=s(this.variable)||s(this.property)){a.charAt(0)!="@"&&(l=/^([^@+\/'"*`(;{}-]*);/.exec(j[f]))?(c+=l[0].length-1,d=new e.Anonymous(l[1])):a==="font"?d=s(this.font):d=s(this.value),k=s(this.important);if(d&&s(this.end))return new e.Rule(a,d,k,h);i=c,q()}},"import":function(){var a;if(s(/^@import\s+/)&&(a=s(this.entities.quoted)||s(this.entities.url))&&s(";"))return new e.Import(a,o)},dir
ective:function(){var a,d,f,g;if(b.charAt(c)==="@"){if(d=s(this["import"]))return d;if(a=s(/^@media|@page|@-[-a-z]+/)){g=(s(/^[^{]+/)||"").trim();if(f=s(this.block))return new e.Directive(a+" "+g,f)}else if(a=s(/^@[-a-z]+/))if(a==="@font-face"){if(f=s(this.block))return new e.Directive(a,f)}else if((d=s(this.entity))&&s(";"))return new e.Directive(a,d)}},font:function(){var a=[],b=[],c,d,f,g;while(g=s(this.shorthand)||s(this.entity))b.push(g);a.push(new e.Expression(b));if(s(","))while(g=s(this.expression)){a.push(g);if(!s(","))break}return new e.Value(a)},value:function(){var a,b=[],c;while(a=s(this.expression)){b.push(a);if(!s(","))break}if(b.length>0)return new e.Value(b)},important:function(){if(b.charAt(c)==="!")return s(/^! *important/)},sub:function(){var a;if(s("(")&&(a=s(this.expression))&&s(")"))return a},multiplication:function
(){var a,b,c,d;if(a=s(this.operand)){while((c=s("/")||s("*"))&&(b=s(this.operand)))d=new e.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,d,f,g;if(a=s(this.multiplication)){while((f=s(/^[-+]\s+/)||b.charAt(c-1)!=" "&&(s("+")||s("-")))&&(d=s(this.multiplication)))g=new e.Operation(f,[g||a,d]);return g||a}},operand:function(){var a,d=b.charAt(c+1);b.charAt(c)==="-"&&(d==="@"||d==="(")&&(a=s("-"));var f=s(this.sub)||s(this.entities.dimension)||s(this.entities.color)||s(this.entities.variable)||s(this.entities.call);return a?new e.Operation("*",[new e.Dimension(-1),f]):f},expression:function(){var a,b,c=[],d;while(a=s(this.addition)||s(this.entity))c.push(a);if(c.length>0)return new e.Expression(c)},property:function(){var a;if(a=s(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}},typeof a!="undefined"&&(d.Parser.importe
r=function(a,b,c,d){a.charAt(0)!=="/"&&b.length>0&&(a=b[0]+a),o({href:a,title:a,type:d.mime},c,!0)}),function(a){function d(a){return Math.min(1,Math.max(0,a))}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){a=a<0?a+1:a>1?a-1:a;return a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(M
ath.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();e.s+=c.value/100,e.s=d(e.s);return b(e)},desaturate:function(a,c){var e=a.toHSL();e.s-=c.value/100,e.s=d(e.s);return b(e)},lighten:function(a,c){var e=a.toHSL();e.l+=c.value/100,e.l=d(e.l);return b(e)},darken:function(a,c){var e=a.toHSL();e.l-=c.value/100,e.l=d(e.l);return b(e)},fadein:function(a,c){var e=a.toHSL();e.a+=c.value/100,e.a=d(e.a);return b(e)},fadeout:function(a,c){var e=a.toHSL();e.a-=c.value/100,e.a=d(e.a);return b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;d.h=e<0?360+e:e;return b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb
[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e<c.length;e++)d=d.replace(/%[sda]/i,function(a){var b=a.match(/s/i)?c[e].value:c[e].toCSS();return a.match(/[A-Z]$/)?encodeURIComponent(b):b});d=d.replace(/%%/g,"%");return new a.Quoted('"'+d+'"',d)},round:function(b){if(b instanceof a.Dimension)return new a.Dimension(Math.round(c(b)),b.unit);if(typeof b=="number")return Math.round(b);throw{error:"RuntimeError",message:"math functions take numbers a
s parameters"}}}}(c("less/tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(){return this}}}(c("less/tree")),function(a){a.Anonymous=function(a){this.value=a.value||a},a.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this}}}(c("less/tree")),function(a){a.Call=function(a,b){this.name=a,this.args=b},a.Call.prototype={eval:function(b){var c=this.args.map(function(a){return a.eval(b)});return this.name in a.functions?a.functions[this.name].apply(a.functions,c):new a.Anonymous(this.name+"("+c.map(function(a){return a.toCSS()}).join(", ")+")")},toCSS:function(a){return this.eval(a).toCSS()}}}(c("less/tree")),function(a){a.Color=function(a,b){Array.isArray(a)?this.rgb=a:a.length==6?this.rgb=a.match(/.{2}/g).map(function(a){return parse
Int(a,16)}):a.length==8?(this.alpha=parseInt(a.substring(0,2),16)/255,this.rgb=a.substr(2).match(/.{2}/g).map(function(a){return parseInt(a,16)})):this.rgb=a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha=typeof b=="number"?b:1},a.Color.prototype={eval:function(){return this},toCSS:function(){return this.alpha<1?"rgba("+this.rgb.map(function(a){return Math.round(a)}).concat(this.alpha).join(", ")+")":"#"+this.rgb.map(function(a){a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16);return a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);swi
tch(e){case a:g=(b-c)/j+(b<c?6:0);break;case b:g=(c-a)/j+2;break;case c:g=(a-b)/j+4}g/=6}return{h:g*360,s:h,l:i,a:d}}}}(c("less/tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("less/tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)}}}(c("less/tree")),function(a){a.Directive=function(b,c){this.name=b,Array.isArray(c)?this.ruleset=new a.Ruleset([],c):this.value=c},a.Directive.prototype={toCSS:function(a,b){if(this.ruleset){this.ruleset.root=!0;return this.name+(b.compress?"{":" {\n "
;)+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n ")+(b.compress?"}":"\n}\n")}return this.name+" "+this.value.toCSS()+";\n"},eval:function(a){a.frames.unshift(this),this.ruleset=this.ruleset&&this.ruleset.eval(a),a.frames.shift();return this},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(c("less/tree")),function(a){a.Element=function(b,c){this.combinator=b instanceof a.Combinator?b:new a.Combinator(b),this.value=c.trim()},a.Element.prototype.toCSS=function(a){return this.combinator.toCSS(a||{})+this.value},a.Combinator=function(a){a===" "?this.value=" ":this.value=a?a.trim():""},a.Combinator.prototype.toCSS=function(a){return{"":""," ":" ","&"
:"",":":" :","::":"::","+":a.compress?"+":" + ","~":a.compress?"~":" ~ ",">":a.compress?">":" > "}[this.value]}}(c("less/tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(" ")}}}(c("less/tree")),function(a){a.Import=function(b,c){var d=this;this._path=b,b instanceof a.Quoted?this.path=/\.(le?|c)ss$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value||b.value,this.css=/css$/.test(this.path),this.css||c.push(this.path,function(a){if(!a)throw new Error("Error parsing "+d.path);d.root=a})},a.Import.prototype={toCSS
:function(){return this.css?"@import "+this._path.toCSS()+";\n":""},eval:function(b){var c;if(this.css)return this;c=new a.Ruleset(null,this.root.rules.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));return c.rules}}}(c("less/tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify((new a.Variable("@"+e,d.index)).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: `"+f+"`",index:this.index}}for(var h in b.frames[0].variables())e[h.slice(1)]={value:b.frames[0].variables()[h].value,toJS:function(){return this.value.eval(b).toCSS()}};try{c=f.call(e)}catch(g){throw{message:&quo
t;JavaScript evaluation error: '"+g.name+": "+g.message+"'",index:this.index}}return typeof c=="string"?new a.Quoted('"'+c+'"',c,this.escaped,this.index):Array.isArray(c)?new a.Anonymous(c.join(", ")):new a.Anonymous(c)}}}(c("less/tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value}}}(c("less/tree")),function(a){a.mixin={},a.mixin.Call=function(b,c,d){this.selector=new a.Selector(b),this.arguments=c,this.index=d},a.mixin.Call.prototype={eval:function(a){var b,c,d=[],e=!1;for(var f=0;f<a.frames.length;f++)if((b=a.frames[f].find(this.selector)).length>0){c=this.arguments&&this.arguments.map(function(b){return b.eval(a)});for(var g=0;g<b.length;g++)if(b[g].match(c,a))try{Array.prototype.push.apply(d,b[g].eval(a,this.arguments).rules),e=!0}catch(h){throw{message:h.message,index:h.index,stack:h.stack,call:this
.index}}if(e)return d;throw{message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(a){return a.toCSS()}).join(", ")+")`",index:this.index}}throw{message:this.selector.toCSS().trim()+" is undefined",index:this.index}}},a.mixin.Definition=function(b,c,d){this.name=b,this.selectors=[new a.Selector([new a.Element(null,b)])],this.params=c,this.arity=c.length,this.rules=d,this._lookups={},this.required=c.reduce(function(a,b){return!b.name||b.name&&!b.value?a+1:a},0),this.parent=a.Ruleset.prototype,this.frames=[]},a.mixin.Definition.prototype={toCSS:function(){return""},variable:function(a){return this.parent.variable.call(this,a)},variables:function(){return this.parent.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},eval:function(b,c){var d=new a.Ruleset(null,[]),e,f=[];
for(var g=0,h;g<this.params.length;g++)if(this.params[g].name)if(h=c&&c[g]||this.params[g].value)d.rules.unshift(new a.Rule(this.params[g].name,h.eval(b)));else throw{message:"wrong number of arguments for "+this.name+" ("+c.length+" for "+this.arity+")"};for(var g=0;g<Math.max(this.params.length,c&&c.length);g++)f.push(c[g]||this.params[g].value);d.rules.unshift(new a.Rule("@arguments",(new a.Expression(f)).eval(b)));return(new a.Ruleset(null,this.rules.slice(0))).eval({frames:[this,d].concat(this.frames,b.frames)})},match:function(a,b){var c=a&&a.length||0,d;if(c<this.required)return!1;if(this.required>0&&c>this.params.length)return!1;d=Math.min(c,this.arity);for(var e=0;e<d;e++)if(!this.params[e].name&&a[e].eval(b).toCSS()!=this.params[e].value.eval(b).toCSS())return!1;return!0}}}(c("less/tree")),function(a){a.Operation=function(a,b){this.op=a.trim(),this.operands
=b},a.Operation.prototype.eval=function(b){var c=this.operands[0].eval(b),d=this.operands[1].eval(b),e;if(c instanceof a.Dimension&&d instanceof a.Color)if(this.op==="*"||this.op==="+")e=d,d=c,c=e;else throw{name:"OperationError",message:"Can't substract or divide a color from a number"};return c.operate(this.op,d)},a.operate=function(a,b,c){switch(a){case"+":return b+c;case"-":return b-c;case"*":return b*c;case"/":return b/c}}}(c("less/tree")),function(a){a.Quoted=function(a,b,c,d){this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d},a.Quoted.prototype={toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(b){var c=this,d=this.value.replace(/`([^`]+)`/g,function(d,e){return(new a.JavaScript(e,c.index,!0)).eval(b).value}).replace(/@\{([\w-]+)\}/g,function(d,e){var f=(new a.Variable("@"+e,c.index)).eval(b);retu
rn f.value||f.toCSS()});return new a.Quoted(this.quote+d+this.quote,d,this.escaped,this.index)}}}(c("less/tree")),function(a){a.Rule=function(b,c,d,e){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.index=e,b.charAt(0)==="@"?this.variable=!0:this.variable=!1},a.Rule.prototype.toCSS=function(a){return this.variable?"":this.name+(a.compress?":":": ")+this.value.toCSS(a)+this.important+";"},a.Rule.prototype.eval=function(b){return new a.Rule(this.name,this.value.eval(b),this.important,this.index)},a.Shorthand=function(a,b){this.a=a,this.b=b},a.Shorthand.prototype={toCSS:function(a){return this.a.toCSS(a)+"/"+this.b.toCSS(a)},eval:function(){return this}}}(c("less/tree")),function(a){a.Ruleset=function(a,b){this.selectors=a,this.rules=b,this._lookups={}},a.Ruleset.prototype={eval:function(b){var c=new a.Ruleset(this.selectors,this.rules
.slice(0));c.root=this.root,b.frames.unshift(c);if(c.root)for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Definition&&(c.rules[d].frames=b.frames.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Call&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0,e;d<c.rules.length;d++)e=c.rules[d],e instanceof a.mixin.Definition||(c.rules[d]=e.eval?e.eval(b):e);b.frames.shift();return c},match:function(a){return!a||a.length===0},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(b,c){c instanceof a.Rule&&c.variable===!0&&(b[c.name]=c);return b},{})},variable:function(a){return this.variables()[a]},rulesets:function(){return this._rulesets?this._rulesets:this._rulesets=this.rules.filter(funct
ion(b){return b instanceof a.Ruleset||b instanceof a.mixin.Definition})},find:function(b,c){c=c||this;var d=[],e,f,g=b.toCSS();if(g in this._lookups)return this._lookups[g];this.rulesets().forEach(function(e){if(e!==c)for(var g=0;g<e.selectors.length;g++)if(f=b.match(e.selectors[g])){b.elements.length>1?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}});return this._lookups[g]=d},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;if(!this.root)if(b.length===0)g=this.selectors.map(function(a){return[a]});else for(var j=0;j<this.selectors.length;j++)for(var k=0;k<b.length;k++)g.push(b[k].concat([this.selectors[j]]));for(var l=0;l<this.rules.length;l++)i=this.rules[l],i.rules||i instanceof a.Directive?f.push(i.toCSS(g,c)):i instanceof a.Comment?i.silent||(this.root?f.push(i.toCSS(c)):e.push(i.toCSS(c))):i.toCSS&&!i.variable?e.push(i.toCSS(c)):i.value&&!i.variable&&e.push(i.value.toString());f=f.join("&
quot;),this.root?d.push(e.join(c.compress?"":"\n")):e.length>0&&(h=g.map(function(a){return a.map(function(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":g.length>3?",\n":", "),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f);return d.join("")+(c.compress?"\n":"")}}}(c("less/tree")),function(a){a.Selector=function(a){this.elements=a,this.elements[0].combinator.value===""&&(this.elements[0].combinator.value=" ")},a.Selector.prototype.match=function(a){return this.elements[0].value===a.elements[0].value?!0:!1},a.Selector.prototype.toCSS=function(a){if(this._css)return this._css;return this._css=this.elements.map(function(b){return typeof b=="string"?" "+b.trim():b.toCSS(a)}).join("")}}(c(&quo
t;less/tree")),function(b){b.URL=function(b,c){b.data?this.attrs=b:(!/^(?:https?:\/|file:\/|data:\/)?\//.test(b.value)&&c.length>0&&typeof a!="undefined"&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("less/tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("less/tree")),function(a){a.Variable=functi
on(a,b){this.name=a,this.index=b},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){
+if(d=a.variable(e))return d.value.eval(b)}))return c;throw{message:"variable "+e+" is undefined",index:this.index}}}}(c("less/tree")),c("less/tree").find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null},c("less/tree").jsify=function(a){return Array.isArray(a.value)&&a.value.length>1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)};var g=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||g?"development":"production"),d.async=!1,d.poll=d.poll||(g?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return
this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&n(function(a,b,c){a&&q(a.toCSS(),b,c.lastModified)})},d.poll)):d.optimization=3;var h;try{h=typeof a.localStorage=="undefined"?null:a.localStorage}catch(i){h=null}var j=document.getElementsByTagName("link"),k=/^text\/(x-)?less$/;d.sheets=[];for(var l=0;l<j.length;l++)(j[l].rel==="stylesheet/less"||j[l].rel.match(/stylesheet/)&&j[l].type.match(k))&&d.sheets.push(j[l]);d.refresh=function(a){var b,c;b=c=new Date,n(function(a,d,e){e.local?u("loading "+d.href+" from cache."):(u("parsed "+d.href+" successfully."),q(a.toCSS(),d,e.lastModified)),u("css for "+d.href+" generated in "+(new Date-c)+"ms"),e.remaining===0&&u("css generated in "+(new Date-b)+"ms"),c=new Date
},a),m()},d.refreshStyles=m,d.refresh(d.env==="development")})(window)
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless113js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.3.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.3.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.3.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2721 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.3
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+ less = exports,
+ tree = require('less/tree');
+} else {
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ mime: env && env.mime, // MIME type of .less files
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (root) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+
+ callback(root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ chunks = [];
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam,
+ inString;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = i;
+
+ if (!inString && !inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ if (c === '{' && !inString && !inParam) { level ++;
+ chunk.push(c);
+ } else if (c === '}' && !inString && !inParam) { level --;
+ chunk.push(c);
+ chunks[++j] = chunk = [];
+ } else if (c === '(' && !inString && !inParam) {
+ chunk.push(c);
+ inParam = true;
+ } else if (c === ')' && !inString && inParam) {
+ chunk.push(c);
+ inParam = false;
+ } else {
+ if (c === '"' || c === "'" || c === '`') {
+ if (! inString) {
+ inString = c;
+ } else {
+ inString = inString === c ? false : inString;
+ }
+ }
+ chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ throw {
+ type: 'Syntax',
+ message: "Missing closing `}`",
+ filename: env.filename
+ };
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [];
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ lines = input.split('\n');
+ line = getLine(e.index);
+
+ for (var n = e.index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ throw {
+ type: e.type,
+ message: e.message,
+ filename: env.filename,
+ index: e.index,
+ line: typeof(line) === 'number' ? line + 1 : null,
+ callLine: e.call && (getLine(e.call) + 1),
+ callExtract: lines[getLine(e.call)],
+ stack: e.stack,
+ column: column,
+ extract: [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ]
+ };
+ }
+ if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+
+ function getLine(index) {
+ return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ name: "ParseError",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+ if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args, index = i;
+
+ if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args, index) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+ if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value;
+
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ while (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ if (value = $(this.expression)) {
+ params.push({ name: param.name, value: value });
+ } else {
+ throw new(Error)("Expected value");
+ }
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ if (! $(',')) { break }
+ }
+ if (! $(')')) throw new(Error)("Expected )");
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset);
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^\(opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c;
+
+ c = $(this.combinator);
+ e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+ if (e) { return new(tree.Element)(c, e) }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '&' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === ':' && input.charAt(i + 1) === ':') {
+ i += 2;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)('::');
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ if (match = /^([.#: \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+ i += match[0].length - 1;
+ selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+ } else {
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url)) &&
+ $(';')) {
+ return new(tree.Import)(path, imports);
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import'])) {
+ return value;
+ } else if (name = $(/^@media|@page|@-[-a-z]+/)) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (typeof(window) !== 'undefined') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (path.charAt(0) !== '/' && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math.round(number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math.round(n);
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "math functions take numbers as parameters"
+ };
+ }
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+ this.name = name;
+ this.args = args;
+ this.index = index;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ try {
+ return tree.functions[this.name].apply(tree.functions, args);
+ } catch (e) {
+ throw { message: "error evaluating function `" + this.name + "`",
+ index: this.index };
+ }
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else if (rgb.length == 8) {
+ this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
+ this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+ this.name = name;
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+ this.value = value.trim();
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ ':' : ' :',
+ '::': '::',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(' ');
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+ var that = this;
+
+ this._path = path;
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (root) {
+ if (! root) {
+ throw new(Error)("Error parsing " + that.path);
+ }
+ that.root = root;
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function () {
+ if (this.css) {
+ return "@import " + this._path.toCSS() + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset;
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return ruleset.rules;
+ }
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index };
+ }
+ }
+ }
+ throw { message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ eval: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+ for (var i = 0, val; i < this.params.length; i++) {
+ if (this.params[i].name) {
+ if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+ } else {
+ throw { message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len;
+
+ if (argsLength < this.required) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return v.value || v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + ";";
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+ ruleset.root = this.root;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > 1) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ for (var s = 0; s < this.selectors.length; s++) {
+ for (var c = 0; c < context.length; c++) {
+ paths.push(context[c].concat([this.selectors[s]]));
+ }
+ }
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ if (this.elements[0].value === other.elements[0].value) {
+ return true;
+ } else {
+ return false;
+ }
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { message: "variable " + name + " is undefined",
+ index: this.index };
+ }
+ }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+require('less/tree').jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:' ||
+ location.protocol === 'chrome:' ||
+ location.protocol === 'chrome-extension:' ||
+ location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (root, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (root, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+ styles[i].type = 'text/css';
+ styles[i].innerHTML = tree.toCSS();
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^(https?|file):/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ css.media = sheet.media || 'screen';
+ css.id = id;
+ document.getElementsByTagName('head')[0].appendChild(css);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? false : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol) {
+ if (xhr.status === 0) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+
+ var template = ['<ul>',
+ '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+ '<li><label>[0]</label><pre>{current}</pre></li>',
+ '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+ '</ul>'].join('\n');
+
+ var elem = document.createElement('div'), timer, content;
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p><a href="' + href + '">' + href + "</a> ";
+
+ if (e.extract) {
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ template.replace(/\[(-?\d)\]/g, function (_, i) {
+ return (parseInt(e.line) + parseInt(i)) || '';
+ }).replace(/\{(\d)\}/g, function (_, i) {
+ return e.extract[parseInt(i)] || '';
+ }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+ e.extract[1].slice(e.column) + '</span>');
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #ee4444;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.ctx {',
+ 'color: #dd4444;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless113minjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.3.min.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.3.min.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.3.min.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.3
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+//
+// LESS - Leaner CSS v1.1.3
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function v(a,b){var c="less-error-message:"+p(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p><a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+":</p>"+e.replace(/\[(-?\d)\]/g,function(b,c){return parseInt(a.line)+parseInt(c)||""}).replace(/\{(\d)\}/g,function(b,c){return a.extract[parseInt(c)]||"&q
uot;}).replace(/\{current\}/,a.extract[1].slice(0,a.column)+'<span class="error">'+a.extract[1].slice(a.column)+"</span>")),f.innerHTML=h,q([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #ee4444;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.ctx {","color: #dd4444;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","
;color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=setInterval(function(){document.body&&(document.getElementById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}function u(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: &quo
t;+a)}function t(a){return a&&a.parentNode.removeChild(a)}function s(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){u("browser doesn't support AJAX.");return null}}function r(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var f=s(),h=g?!1:d.async;typeof f.overrideMimeType=="function"&&f.overrideMimeType("text/css"),f.open("GET",a,h),f.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),f.send(null),g?f.status===0?c(f.responseText):e(f.status,a):h?f.onreadystatechange=function(){f.readyState==4&&i(f,c,e)}:i(f,c,e)}function q(a,b,c){var d,e=b.href?b.href.replace(/\?.*$/,""):"",f="less:"+(b.title||p(e));(d=document.getElementById(f))===null&
&(d=document.createElement("style"),d.type="text/css",d.media=b.media||"screen",d.id=f,document.getElementsByTagName("head")[0].appendChild(d));if(d.styleSheet)try{d.styleSheet.cssText=a}catch(g){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(a){d.childNodes.length>0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&h&&(u("saving "+e+" to cache."),h.setItem(e,a),h.setItem(e+":timestamp",c))}function p(a){return a.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\?.*$/,"").replace(/\.[^\.\/]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function o(b,c,e,f){var g=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/,""),j=h&&h.getItem(i),k=h&&h.getItem(i+":ti
mestamp"),l={css:j,timestamp:k};/^(https?|file):/.test(i)||(i.charAt(0)=="/"?i=a.location.protocol+"//"+a.location.host+i:i=g.slice(0,g.lastIndexOf("/")+1)+i),r(b.href,b.type,function(a,g){if(!e&&l&&g&&(new Date(g)).valueOf()===(new Date(l.timestamp)).valueOf())q(l.css,b),c(null,b,{local:!0,remaining:f});else try{(new d.Parser({optimization:d.optimization,paths:[i.replace(/[\w\.-]+$/,"")],mime:b.type})).parse(a,function(a,d){if(a)return v(a,i);try{c(d,b,{local:!1,lastModified:g,remaining:f}),t(document.getElementById("less-error-message:"+p(i)))}catch(a){v(a,i)}})}catch(h){v(h,i)}},function(a,b){throw new Error("Couldn't load "+b+" ("+a+")")})}function n(a,b){for(var c=0;c<d.sheets.length;c++)o(d.sheets[c],a,b,d.sheets.length-(c+1))}function m(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(k)&&(new d.Parser).p
arse(a[b].innerHTML||"",function(c,d){a[b].type="text/css",a[b].innerHTML=d.toCSS()})}function c(b){return a.less[b.split("/")[1]]}Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d<c;d++)d in this&&a.call(b,this[d],d,this)}),Array.prototype.map||(Array.prototype.map=function(a){var b=this.length>>>0,c=Array(b),d=arguments[1];for(var e=0;e<b;e++)e in this&&(c[e]=a.call(d,this[e],e,this));return c}),Array.prototype.filter||(Array.prototype.filter=function(a){var b=[],c=arguments[1];for(var d=0;d<this.length;d++)a.call(c,this[d])&&b.push(this[d]);return b}),Array.prototype.reduce||(Array.prototype.reduce=function(a){var b=this.length>>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.leng
th>=2)var d=arguments[1];else for(;;){if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}for(;c<b;c++)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){var b=this.length,c=arguments[1]||0;if(!b)return-1;if(c>=b)return-1;c<0&&(c+=b);for(;c<b;c++){if(!Object.prototype.hasOwnProperty.call(this,c))continue;if(a===this[c])return c}return-1}),Object.keys||(Object.keys=function(a){var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}),String.prototype.trim||(String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")});var d,e;typeof a=="undefined"?(d=exports,e=c("less/tree")):(typeof a.less=="undefined"&&(a.less={}),d=a.less,e=a.less.tree={}),d.Parser=function(a){function t(a){return typeof a=="string"?b.charAt(c)===a:a.test(j[f])?!0:!1
}function s(a){var d,e,g,h,i,m,n,o;if(a instanceof Function)return a.call(l.parsers);if(typeof a=="string")d=b.charAt(c)===a?a:null,g=1,r();else{r();if(d=a.exec(j[f]))g=d[0].length;else return null}if(d){o=c+=g,m=c+j[f].length-g;while(c<m){h=b.charCodeAt(c);if(h!==32&&h!==10&&h!==9)break;c++}j[f]=j[f].slice(g+(c-o)),k=c,j[f].length===0&&f<j.length-1&&f++;return typeof d=="string"?d:d.length===1?d[0]:d}}function r(){c>k&&(j[f]=j[f].slice(c-k),k=c)}function q(){j[f]=g,c=h,k=c}function p(){g=j[f],h=c,k=c}var b,c,f,g,h,i,j,k,l,m=this,n=function(){},o=this.imports={paths:a&&a.paths||[],queue:[],files:{},mime:a&&a.mime,push:function(b,c){var e=this;this.queue.push(b),d.Parser.importer(b,this.paths,function(a){e.queue.splice(e.queue.indexOf(b),1),e.files[b]=a,c(a),e.queue.length===0&&n()},a)}};this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.fi
lename=this.env.filename||null;return l={imports:o,parse:function(d,g){var h,l,m,o,p,q,r=[],t,u=null;c=f=k=i=0,j=[],b=d.replace(/\r\n/g,"\n"),j=function(c){var d=0,e=/[^"'`\{\}\/\(\)]+/g,f=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,g=0,h,i=c[0],j,k;for(var l=0,m,n;l<b.length;l++){e.lastIndex=l,(h=e.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0])),m=b.charAt(l),f.lastIndex=l,!k&&!j&&m==="/"&&(n=b.charAt(l+1),(n==="/"||n==="*")&&(h=f.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0]),m=b.charAt(l)));if(m==="{"&&!k&&!j)g++,i.push(m);else if(m==="}"&&!k&&!j)g--,i.push(m),c[++d]=i=[];else if(m==="("&&!k&&!j)i.push(m),j=!0;else if(m===")"&&!k&&j)i.push(m),j=!1;else{if(m==='"'||m==="'"||m==="`")k?k=k===m?!1:k:k=m;i.push(m)}}if(g>0)throw{type:"S
yntax",message:"Missing closing `}`",filename:a.filename};return c.map(function(a){return a.join("")})}([[]]),h=new e.Ruleset([],s(this.parsers.primary)),h.root=!0,h.toCSS=function(c){var d,f,g;return function(g,h){function n(a){return a?(b.slice(0,a).match(/\n/g)||"").length:null}var i=[];g=g||{},typeof h=="object"&&!Array.isArray(h)&&(h=Object.keys(h).map(function(a){var b=h[a];b instanceof e.Value||(b instanceof e.Expression||(b=new e.Expression([b])),b=new e.Value([b]));return new e.Rule("@"+a,b,!1,0)}),i=[new e.Ruleset(null,h)]);try{var j=c.call(this,{frames:i}).toCSS([],{compress:g.compress||!1})}catch(k){f=b.split("\n"),d=n(k.index);for(var l=k.index,m=-1;l>=0&&b.charAt(l)!=="\n";l--)m++;throw{type:k.type,message:k.message,filename:a.filename,index:k.index,line:typeof d=="number"?d+1:null,callLine:k.call&&n(k.call)+1,callExtract:f[n(k.call)],stack:k.stack,co
lumn:m,extract:[f[d-1],f[d],f[d+1]]}}return g.compress?j.replace(/(\s)+/g,"$1"):j}}(h.eval);if(c<b.length-1){c=i,q=b.split("\n"),p=(b.slice(0,c).match(/\n/g)||"").length+1;for(var v=c,w=-1;v>=0&&b.charAt(v)!=="\n";v--)w++;u={name:"ParseError",message:"Syntax Error on line "+p,index:c,filename:a.filename,line:p,column:w,extract:[q[p-2],q[p-1],q[p]]}}this.imports.queue.length>0?n=function(){g(u,h)}:g(u,h)},parsers:{primary:function(){var a,b=[];while((a=s(this.mixin.definition)||s(this.rule)||s(this.ruleset)||s(this.mixin.call)||s(this.comment)||s(this.directive))||s(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(b.charAt(c)==="/"){if(b.charAt(c+1)==="/")return new e.Comment(s(/^\/\/.*/),!0);if(a=s(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new e.Comment(a)}},entities:{quoted:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)==='&q
uot;'||b.charAt(d)==="'"){f&&s("~");if(a=s(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new e.Quoted(a[0],a[1]||a[2],f)}},keyword:function(){var a;if(a=s(/^[A-Za-z-]+/))return new e.Keyword(a)},call:function(){var a,b,d=c;if(!!(a=/^([\w-]+|%)\(/.exec(j[f]))){a=a[1].toLowerCase();if(a==="url")return null;c+=a.length;if(a==="alpha")return s(this.alpha);s("("),b=s(this.entities.arguments);if(!s(")"))return;if(a)return new e.Call(a,b,d)}},arguments:function(){var a=[],b;while(b=s(this.expression)){a.push(b);if(!s(","))break}return a},literal:function(){return s(this.entities.dimension)||s(this.entities.color)||s(this.entities.quoted)},url:function(){var a;if(b.charAt(c)==="u"&&!!s(/^url\(/)){a=s(this.entities.quoted)||s(this.entities.variable)||s(this.entities.dataURI)||s(/^[-\w%@$\/.&=:;#+?~]+/)||"";if(!s(")"))throw new Error("missing
closing ) for url()");return new e.URL(a.value||a.data||a instanceof e.Variable?a:new e.Anonymous(a),o.paths)}},dataURI:function(){var a;if(s(/^data:/)){a={},a.mime=s(/^[^\/]+\/[^,;)]+/)||"",a.charset=s(/^;\s*charset=[^,;)]+/)||"",a.base64=s(/^;\s*base64/)||"",a.data=s(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var a,d=c;if(b.charAt(c)==="@"&&(a=s(/^@@?[\w-]+/)))return new e.Variable(a,d)},color:function(){var a;if(b.charAt(c)==="#"&&(a=s(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new e.Color(a[1])},dimension:function(){var a,d=b.charCodeAt(c);if(!(d>57||d<45||d===47))if(a=s(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new e.Dimension(a[1],a[2])},javascript:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)==="`"){f&&s("~");if(a=s(/^`([^`]*)`/))return new e.JavaScript(a[1],c,f)}}},variable:function()
{var a;if(b.charAt(c)==="@"&&(a=s(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!!t(/^[@\w.%-]+\/[@\w.-]+/)&&(a=s(this.entity))&&s("/")&&(b=s(this.entity)))return new e.Shorthand(a,b)},mixin:{call:function(){var a=[],d,f,g,h=c,i=b.charAt(c);if(i==="."||i==="#"){while(d=s(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))a.push(new e.Element(f,d)),f=s(">");s("(")&&(g=s(this.entities.arguments))&&s(")");if(a.length>0&&(s(";")||t("}")))return new e.mixin.Call(a,g,h)}},definition:function(){var a,d=[],f,g,h,i;if(!(b.charAt(c)!=="."&&b.charAt(c)!=="#"||t(/^[^{]*(;|})/)))if(f=s(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=f[1];while(h=s(this.entities.variable)||s(this.entities.literal)||s(this.entities.keyword)){if(h instanceof e.Variable)if(s(":"))if(i=s(
this.expression))d.push({name:h.name,value:i});else throw new Error("Expected value");else d.push({name:h.name});else d.push({value:h});if(!s(","))break}if(!s(")"))throw new Error("Expected )");g=s(this.block);if(g)return new e.mixin.Definition(a,d,g)}}},entity:function(){return s(this.entities.literal)||s(this.entities.variable)||s(this.entities.url)||s(this.entities.call)||s(this.entities.keyword)||s(this.entities.javascript)||s(this.comment)},end:function(){return s(";")||t("}")},alpha:function(){var a;if(!!s(/^\(opacity=/i))if(a=s(/^\d+/)||s(this.entities.variable)){if(!s(")"))throw new Error("missing closing ) for alpha()");return new e.Alpha(a)}},element:function(){var a,b,c;c=s(this.combinator),a=s(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||s("*")||s(this.attribute)||s(/^\([^)@]+\)/);if(a)return new e.Element(c,a)},combinator:function(){var a,d=b.charAt(c);if(d===&
quot;>"||d==="&"||d==="+"||d==="~"){c++;while(b.charAt(c)===" ")c++;return new e.Combinator(d)}if(d===":"&&b.charAt(c+1)===":"){c+=2;while(b.charAt(c)===" ")c++;return new e.Combinator("::")}return b.charAt(c-1)===" "?new e.Combinator(" "):new e.Combinator(null)},selector:function(){var a,d,f=[],g,h;while(d=s(this.element)){g=b.charAt(c),f.push(d);if(g==="{"||g==="}"||g===";"||g===",")break}if(f.length>0)return new e.Selector(f)},tag:function(){return s(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||s("*")},attribute:function(){var a="",b,c,d;if(!!s("[")){if(b=s(/^[a-zA-Z-]+/)||s(this.entities.quoted))(d=s(/^[|~*$^]?=/))&&(c=s(this.entities.quoted)||s(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!s("]"))return;if(a)return"["+a+"]"}},block:function(){va
r a;if(s("{")&&(a=s(this.primary))&&s("}"))return a},ruleset:function(){var a=[],b,d,g;p();if(g=/^([.#: \w-]+)[\s\n]*\{/.exec(j[f]))c+=g[0].length-1,a=[new e.Selector([new e.Element(null,g[1])])];else while(b=s(this.selector)){a.push(b),s(this.comment);if(!s(","))break;s(this.comment)}if(a.length>0&&(d=s(this.block)))return new e.Ruleset(a,d);i=c,q()},rule:function(){var a,d,g=b.charAt(c),k,l;p();if(g!=="."&&g!=="#"&&g!=="&")if(a=s(this.variable)||s(this.property)){a.charAt(0)!="@"&&(l=/^([^@+\/'"*`(;{}-]*);/.exec(j[f]))?(c+=l[0].length-1,d=new e.Anonymous(l[1])):a==="font"?d=s(this.font):d=s(this.value),k=s(this.important);if(d&&s(this.end))return new e.Rule(a,d,k,h);i=c,q()}},"import":function(){var a;if(s(/^@import\s+/)&&(a=s(this.entities.quoted)||s(this.entities.url))&&s(";"))return new e.Import(a
,o)},directive:function(){var a,d,f,g;if(b.charAt(c)==="@"){if(d=s(this["import"]))return d;if(a=s(/^@media|@page|@-[-a-z]+/)){g=(s(/^[^{]+/)||"").trim();if(f=s(this.block))return new e.Directive(a+" "+g,f)}else if(a=s(/^@[-a-z]+/))if(a==="@font-face"){if(f=s(this.block))return new e.Directive(a,f)}else if((d=s(this.entity))&&s(";"))return new e.Directive(a,d)}},font:function(){var a=[],b=[],c,d,f,g;while(g=s(this.shorthand)||s(this.entity))b.push(g);a.push(new e.Expression(b));if(s(","))while(g=s(this.expression)){a.push(g);if(!s(","))break}return new e.Value(a)},value:function(){var a,b=[],c;while(a=s(this.expression)){b.push(a);if(!s(","))break}if(b.length>0)return new e.Value(b)},important:function(){if(b.charAt(c)==="!")return s(/^! *important/)},sub:function(){var a;if(s("(")&&(a=s(this.expression))&&s(")"))return a},multiplication:
function(){var a,b,c,d;if(a=s(this.operand)){while((c=s("/")||s("*"))&&(b=s(this.operand)))d=new e.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,d,f,g;if(a=s(this.multiplication)){while((f=s(/^[-+]\s+/)||b.charAt(c-1)!=" "&&(s("+")||s("-")))&&(d=s(this.multiplication)))g=new e.Operation(f,[g||a,d]);return g||a}},operand:function(){var a,d=b.charAt(c+1);b.charAt(c)==="-"&&(d==="@"||d==="(")&&(a=s("-"));var f=s(this.sub)||s(this.entities.dimension)||s(this.entities.color)||s(this.entities.variable)||s(this.entities.call);return a?new e.Operation("*",[new e.Dimension(-1),f]):f},expression:function(){var a,b,c=[],d;while(a=s(this.addition)||s(this.entity))c.push(a);if(c.length>0)return new e.Expression(c)},property:function(){var a;if(a=s(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}},typeof a!="undefined"&&(d.Parser
.importer=function(a,b,c,d){a.charAt(0)!=="/"&&b.length>0&&(a=b[0]+a),o({href:a,title:a,type:d.mime},c,!0)}),function(a){function d(a){return Math.min(1,Math.max(0,a))}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){a=a<0?a+1:a>1?a-1:a;return a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dim
ension(Math.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();e.s+=c.value/100,e.s=d(e.s);return b(e)},desaturate:function(a,c){var e=a.toHSL();e.s-=c.value/100,e.s=d(e.s);return b(e)},lighten:function(a,c){var e=a.toHSL();e.l+=c.value/100,e.l=d(e.l);return b(e)},darken:function(a,c){var e=a.toHSL();e.l-=c.value/100,e.l=d(e.l);return b(e)},fadein:function(a,c){var e=a.toHSL();e.a+=c.value/100,e.a=d(e.a);return b(e)},fadeout:function(a,c){var e=a.toHSL();e.a-=c.value/100,e.a=d(e.a);return b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;d.h=e<0?360+e:e;return b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]
*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e<c.length;e++)d=d.replace(/%[sda]/i,function(a){var b=a.match(/s/i)?c[e].value:c[e].toCSS();return a.match(/[A-Z]$/)?encodeURIComponent(b):b});d=d.replace(/%%/g,"%");return new a.Quoted('"'+d+'"',d)},round:function(b){if(b instanceof a.Dimension)return new a.Dimension(Math.round(c(b)),b.unit);if(typeof b=="number")return Math.round(b);throw{error:"RuntimeError",message:"math functions take n
umbers as parameters"}}}}(c("less/tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(a){this.value.eval&&(this.value=this.value.eval(a));return this}}}(c("less/tree")),function(a){a.Anonymous=function(a){this.value=a.value||a},a.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this}}}(c("less/tree")),function(a){a.Call=function(a,b,c){this.name=a,this.args=b,this.index=c},a.Call.prototype={eval:function(b){var c=this.args.map(function(a){return a.eval(b)});if(!(this.name in a.functions))return new a.Anonymous(this.name+"("+c.map(function(a){return a.toCSS()}).join(", ")+")");try{return a.functions[this.name].apply(a.functions,c)}catch(d){throw{message:"error evaluating function `"+this.name+"`",index:this.index}}}
,toCSS:function(a){return this.eval(a).toCSS()}}}(c("less/tree")),function(a){a.Color=function(a,b){Array.isArray(a)?this.rgb=a:a.length==6?this.rgb=a.match(/.{2}/g).map(function(a){return parseInt(a,16)}):a.length==8?(this.alpha=parseInt(a.substring(0,2),16)/255,this.rgb=a.substr(2).match(/.{2}/g).map(function(a){return parseInt(a,16)})):this.rgb=a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha=typeof b=="number"?b:1},a.Color.prototype={eval:function(){return this},toCSS:function(){return this.alpha<1?"rgba("+this.rgb.map(function(a){return Math.round(a)}).concat(this.alpha).join(", ")+")":"#"+this.rgb.map(function(a){a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16);return a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c
.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);switch(e){case a:g=(b-c)/j+(b<c?6:0);break;case b:g=(c-a)/j+2;break;case c:g=(a-b)/j+4}g/=6}return{h:g*360,s:h,l:i,a:d}}}}(c("less/tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("less/tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)}}}(c("less/tree")),function(a){a.Directive=function(b,c){this.name=b,A
rray.isArray(c)?this.ruleset=new a.Ruleset([],c):this.value=c},a.Directive.prototype={toCSS:function(a,b){if(this.ruleset){this.ruleset.root=!0;return this.name+(b.compress?"{":" {\n ")+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n ")+(b.compress?"}":"\n}\n")}return this.name+" "+this.value.toCSS()+";\n"},eval:function(a){a.frames.unshift(this),this.ruleset=this.ruleset&&this.ruleset.eval(a),a.frames.shift();return this},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(c("less/tree")),function(a){a.Element=function(b,c){this.combinator=b instanceof a.Combinator?b:new a.Combinator(b),this.value=c.trim()},a.Element.prototype.toCSS=function(a){return this.combinator.toCSS(a||{})+this.value},a.Combinator=functi
on(a){a===" "?this.value=" ":this.value=a?a.trim():""},a.Combinator.prototype.toCSS=function(a){return{"":""," ":" ","&":"",":":" :","::":"::","+":a.compress?"+":" + ","~":a.compress?"~":" ~ ",">":a.compress?">":" > "}[this.value]}}(c("less/tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(" ")}}}(c("less/tree")),function(a){a.Import=function(b,c){var d=this;this._path=b,b instanceof a.Quoted?this.path=/\.(le?|c)ss$/.test(b.value)?b.value:b.value+".less&
quot;:this.path=b.value.value||b.value,this.css=/css$/.test(this.path),this.css||c.push(this.path,function(a){if(!a)throw new Error("Error parsing "+d.path);d.root=a})},a.Import.prototype={toCSS:function(){return this.css?"@import "+this._path.toCSS()+";\n":""},eval:function(b){var c;if(this.css)return this;c=new a.Ruleset(null,this.root.rules.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));return c.rules}}}(c("less/tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify((new a.Variable("@"+e,d.index)).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: `"+f+"`",
index:this.index}}for(var h in b.frames[0].variables())e[h.slice(1)]={value:b.frames[0].variables()[h].value,toJS:function(){return this.value.eval(b).toCSS()}};try{c=f.call(e)}catch(g){throw{message:"JavaScript evaluation error: '"+g.name+": "+g.message+"'",index:this.index}}return typeof c=="string"?new a.Quoted('"'+c+'"',c,this.escaped,this.index):Array.isArray(c)?new a.Anonymous(c.join(", ")):new a.Anonymous(c)}}}(c("less/tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value}}}(c("less/tree")),function(a){a.mixin={},a.mixin.Call=function(b,c,d){this.selector=new a.Selector(b),this.arguments=c,this.index=d},a.mixin.Call.prototype={eval:function(a){var b,c,d=[],e=!1;for(var f=0;f<a.frames.length;f++)if((b=a.frames[f].find(this.selector)).length>0){c=this.arguments&&this.arguments.map(function(b){return
b.eval(a)});for(var g=0;g<b.length;g++)if(b[g].match(c,a))try{Array.prototype.push.apply(d,b[g].eval(a,this.arguments).rules),e=!0}catch(h){throw{message:h.message,index:h.index,stack:h.stack,call:this.index}}if(e)return d;throw{message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(a){return a.toCSS()}).join(", ")+")`",index:this.index}}throw{message:this.selector.toCSS().trim()+" is undefined",index:this.index}}},a.mixin.Definition=function(b,c,d){this.name=b,this.selectors=[new a.Selector([new a.Element(null,b)])],this.params=c,this.arity=c.length,this.rules=d,this._lookups={},this.required=c.reduce(function(a,b){return!b.name||b.name&&!b.value?a+1:a},0),this.parent=a.Ruleset.prototype,this.frames=[]},a.mixin.Definition.prototype={toCSS:function(){return""},variable:function(a){return this.parent.variable.call(this,a)},variables:function(){return this.pare
nt.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},eval:function(b,c){var d=new a.Ruleset(null,[]),e,f=[];for(var g=0,h;g<this.params.length;g++)if(this.params[g].name)if(h=c&&c[g]||this.params[g].value)d.rules.unshift(new a.Rule(this.params[g].name,h.eval(b)));else throw{message:"wrong number of arguments for "+this.name+" ("+c.length+" for "+this.arity+")"};for(var g=0;g<Math.max(this.params.length,c&&c.length);g++)f.push(c[g]||this.params[g].value);d.rules.unshift(new a.Rule("@arguments",(new a.Expression(f)).eval(b)));return(new a.Ruleset(null,this.rules.slice(0))).eval({frames:[this,d].concat(this.frames,b.frames)})},match:function(a,b){var c=a&&a.length||0,d;if(c<this.required)return!1;if(this.required>0&&c>this.params.length)return!1;d=Math.min(c,this.arity);for(var e=0;e<d;e++)if(
!this.params[e].name&&a[e].eval(b).toCSS()!=this.params[e].value.eval(b).toCSS())return!1;return!0}}}(c("less/tree")),function(a){a.Operation=function(a,b){this.op=a.trim(),this.operands=b},a.Operation.prototype.eval=function(b){var c=this.operands[0].eval(b),d=this.operands[1].eval(b),e;if(c instanceof a.Dimension&&d instanceof a.Color)if(this.op==="*"||this.op==="+")e=d,d=c,c=e;else throw{name:"OperationError",message:"Can't substract or divide a color from a number"};return c.operate(this.op,d)},a.operate=function(a,b,c){switch(a){case"+":return b+c;case"-":return b-c;case"*":return b*c;case"/":return b/c}}}(c("less/tree")),function(a){a.Quoted=function(a,b,c,d){this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d},a.Quoted.prototype={toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(b){var c=thi
s,d=this.value.replace(/`([^`]+)`/g,function(d,e){return(new a.JavaScript(e,c.index,!0)).eval(b).value}).replace(/@\{([\w-]+)\}/g,function(d,e){var f=(new a.Variable("@"+e,c.index)).eval(b);return f.value||f.toCSS()});return new a.Quoted(this.quote+d+this.quote,d,this.escaped,this.index)}}}(c("less/tree")),function(a){a.Rule=function(b,c,d,e){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.index=e,b.charAt(0)==="@"?this.variable=!0:this.variable=!1},a.Rule.prototype.toCSS=function(a){return this.variable?"":this.name+(a.compress?":":": ")+this.value.toCSS(a)+this.important+";"},a.Rule.prototype.eval=function(b){return new a.Rule(this.name,this.value.eval(b),this.important,this.index)},a.Shorthand=function(a,b){this.a=a,this.b=b},a.Shorthand.prototype={toCSS:function(a){return this.a.toCSS(a)+"/"+this.b.toCSS(a)},eval:function(){retu
rn this}}}(c("less/tree")),function(a){a.Ruleset=function(a,b){this.selectors=a,this.rules=b,this._lookups={}},a.Ruleset.prototype={eval:function(b){var c=new a.Ruleset(this.selectors,this.rules.slice(0));c.root=this.root,b.frames.unshift(c);if(c.root)for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Definition&&(c.rules[d].frames=b.frames.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Call&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0,e;d<c.rules.length;d++)e=c.rules[d],e instanceof a.mixin.Definition||(c.rules[d]=e.eval?e.eval(b):e);b.frames.shift();return c},match:function(a){return!a||a.length===0},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(b,c){c instanceof a.Rule&
;&c.variable===!0&&(b[c.name]=c);return b},{})},variable:function(a){return this.variables()[a]},rulesets:function(){return this._rulesets?this._rulesets:this._rulesets=this.rules.filter(function(b){return b instanceof a.Ruleset||b instanceof a.mixin.Definition})},find:function(b,c){c=c||this;var d=[],e,f,g=b.toCSS();if(g in this._lookups)return this._lookups[g];this.rulesets().forEach(function(e){if(e!==c)for(var g=0;g<e.selectors.length;g++)if(f=b.match(e.selectors[g])){b.elements.length>1?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}});return this._lookups[g]=d},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;if(!this.root)if(b.length===0)g=this.selectors.map(function(a){return[a]});else for(var j=0;j<this.selectors.length;j++)for(var k=0;k<b.length;k++)g.push(b[k].concat([this.selectors[j]]));for(var l=0;l<this.rules.length;l++)i=this.rules[l],i.rules||i instanceof a.Directive?f.push(i.toCSS(g,c)):i instan
ceof a.Comment?i.silent||(this.root?f.push(i.toCSS(c)):e.push(i.toCSS(c))):i.toCSS&&!i.variable?e.push(i.toCSS(c)):i.value&&!i.variable&&e.push(i.value.toString());f=f.join(""),this.root?d.push(e.join(c.compress?"":"\n")):e.length>0&&(h=g.map(function(a){return a.map(function(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":g.length>3?",\n":", "),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f);return d.join("")+(c.compress?"\n":"")}}}(c("less/tree")),function(a){a.Selector=function(a){this.elements=a,this.elements[0].combinator.value===""&&(this.elements[0].combinator.value=" ")},a.Selector.prototype.match=function(a){return this.elements[0].value===a.elements[0].value?!0:!1},a.Selector.
prototype.toCSS=function(a){if(this._css)return this._css;return this._css=this.elements.map(function(b){return typeof b=="string"?" "+b.trim():b.toCSS(a)}).join("")}}(c("less/tree")),function(b){b.URL=function(b,c){b.data?this.attrs=b:(!/^(?:https?:\/|file:\/|data:\/)?\//.test(b.value)&&c.length>0&&typeof a!="undefined"&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("less/tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(funct
ion(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("less/tree")),function(a){a.Variable=function(a,b){this.name=a,this
+.index=b},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{message:"variable "+e+" is undefined",index:this.index}}}}(c("less/tree")),c("less/tree").find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null},c("less/tree").jsify=function(a){return Array.isArray(a.value)&&a.value.length>1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)};var g=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="local
host"||location.port.length>0||g?"development":"production"),d.async=!1,d.poll=d.poll||(g?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&n(function(a,b,c){a&&q(a.toCSS(),b,c.lastModified)})},d.poll)):d.optimization=3;var h;try{h=typeof a.localStorage=="undefined"?null:a.localStorage}catch(i){h=null}var j=document.getElementsByTagName("link"),k=/^text\/(x-)?less$/;d.sheets=[];for(var l=0;l<j.length;l++)(j[l].rel==="stylesheet/less"||j[l].rel.match(/stylesheet/)&&j[l].type.match(k))&&d.sheets.push(j[l]);d.refresh=function(a){var b,c;b=c=new Date,n(function(a,d,e){e.local?u("loading "+d.href+" from cache."):(u("parsed "+d.href+" successfully."),q(a.toCSS(),
d,e.lastModified)),u("css for "+d.href+" generated in "+(new Date-c)+"ms"),e.remaining===0&&u("css generated in "+(new Date-b)+"ms"),c=new Date},a),m()},d.refreshStyles=m,d.refresh(d.env==="development")})(window)
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless114js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.4.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.4.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.4.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2769 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.4
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+ less = exports,
+ tree = require('less/tree');
+} else {
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ mime: env && env.mime, // MIME type of .less files
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (root) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+
+ callback(root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ chunks = [];
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam,
+ inString;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = i;
+
+ if (!inString && !inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ if (c === '{' && !inString && !inParam) { level ++;
+ chunk.push(c);
+ } else if (c === '}' && !inString && !inParam) { level --;
+ chunk.push(c);
+ chunks[++j] = chunk = [];
+ } else if (c === '(' && !inString && !inParam) {
+ chunk.push(c);
+ inParam = true;
+ } else if (c === ')' && !inString && inParam) {
+ chunk.push(c);
+ inParam = false;
+ } else {
+ if (c === '"' || c === "'" || c === '`') {
+ if (! inString) {
+ inString = c;
+ } else {
+ inString = inString === c ? false : inString;
+ }
+ }
+ chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ throw {
+ type: 'Syntax',
+ message: "Missing closing `}`",
+ filename: env.filename
+ };
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [];
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ lines = input.split('\n');
+ line = getLine(e.index);
+
+ for (var n = e.index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ throw {
+ type: e.type,
+ message: e.message,
+ filename: env.filename,
+ index: e.index,
+ line: typeof(line) === 'number' ? line + 1 : null,
+ callLine: e.call && (getLine(e.call) + 1),
+ callExtract: lines[getLine(e.call)],
+ stack: e.stack,
+ column: column,
+ extract: [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ]
+ };
+ }
+ if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+
+ function getLine(index) {
+ return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ name: "ParseError",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+ if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args, index = i;
+
+ if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args, index) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+ if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value;
+
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ while (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ if (value = $(this.expression)) {
+ params.push({ name: param.name, value: value });
+ } else {
+ throw new(Error)("Expected value");
+ }
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ if (! $(',')) { break }
+ }
+ if (! $(')')) throw new(Error)("Expected )");
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset);
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^\(opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c;
+
+ c = $(this.combinator);
+ e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/) || $(/^(?:\d*\.)?\d+%/);
+
+ if (e) { return new(tree.Element)(c, e) }
+
+ if (c.value && c.value[0] === '&') {
+ return new(tree.Element)(c, null);
+ }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === '&') {
+ match = '&';
+ i++;
+ if(input.charAt(i) === ' ') {
+ match = '& ';
+ }
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(match);
+ } else if (c === ':' && input.charAt(i + 1) === ':') {
+ i += 2;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)('::');
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ if (match = /^([.#:% \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+ i += match[0].length - 1;
+ selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+ } else {
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url)) &&
+ $(';')) {
+ return new(tree.Import)(path, imports);
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import'])) {
+ return value;
+ } else if (name = $(/^@media|@page/) || $(/^@(?:-webkit-)?keyframes/)) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (typeof(window) !== 'undefined') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (path.charAt(0) !== '/' && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math.round(number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math.round(n);
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "math functions take numbers as parameters"
+ };
+ }
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+ this.name = name;
+ this.args = args;
+ this.index = index;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ try {
+ return tree.functions[this.name].apply(tree.functions, args);
+ } catch (e) {
+ throw { message: "error evaluating function `" + this.name + "`",
+ index: this.index };
+ }
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else if (rgb.length == 8) {
+ this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
+ this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+ this.name = name;
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+ this.value = value ? value.trim() : "";
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else if (value === '& ') {
+ this.value = '& ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ '& ' : ' ',
+ ':' : ' :',
+ '::': '::',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(' ');
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+ var that = this;
+
+ this._path = path;
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (root) {
+ if (! root) {
+ throw new(Error)("Error parsing " + that.path);
+ }
+ that.root = root;
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function () {
+ if (this.css) {
+ return "@import " + this._path.toCSS() + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset;
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return ruleset.rules;
+ }
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index };
+ }
+ }
+ }
+ throw { message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ eval: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+ for (var i = 0, val; i < this.params.length; i++) {
+ if (this.params[i].name) {
+ if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+ } else {
+ throw { message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len;
+
+ if (argsLength < this.required) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return v.value || v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + ";";
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+ ruleset.root = this.root;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > 1) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ this.joinSelectors( paths, context, this.selectors );
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ },
+
+ joinSelectors: function (paths, context, selectors) {
+ for (var s = 0; s < selectors.length; s++) {
+ this.joinSelector(paths, context, selectors[s]);
+ }
+ },
+
+ joinSelector: function (paths, context, selector) {
+ var before = [], after = [], beforeElements = [],
+ afterElements = [], hasParentSelector = false, el;
+
+ for (var i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ if (el.combinator.value[0] === '&') {
+ hasParentSelector = true;
+ }
+ if (hasParentSelector) afterElements.push(el);
+ else beforeElements.push(el);
+ }
+
+ if (! hasParentSelector) {
+ afterElements = beforeElements;
+ beforeElements = [];
+ }
+
+ if (beforeElements.length > 0) {
+ before.push(new(tree.Selector)(beforeElements));
+ }
+
+ if (afterElements.length > 0) {
+ after.push(new(tree.Selector)(afterElements));
+ }
+
+ for (var c = 0; c < context.length; c++) {
+ paths.push(before.concat(context[c]).concat(after));
+ }
+ }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ if (this.elements[0].value === other.elements[0].value) {
+ return true;
+ } else {
+ return false;
+ }
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { message: "variable " + name + " is undefined",
+ index: this.index };
+ }
+ }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+require('less/tree').jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:' ||
+ location.protocol === 'chrome:' ||
+ location.protocol === 'chrome-extension:' ||
+ location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (root, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (root, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+ styles[i].type = 'text/css';
+ styles[i].innerHTML = tree.toCSS();
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^(https?|file):/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ css.media = sheet.media || 'screen';
+ css.id = id;
+ document.getElementsByTagName('head')[0].appendChild(css);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? false : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol) {
+ if (xhr.status === 0) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+
+ var template = ['<ul>',
+ '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+ '<li><label>[0]</label><pre>{current}</pre></li>',
+ '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+ '</ul>'].join('\n');
+
+ var elem = document.createElement('div'), timer, content;
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p><a href="' + href + '">' + href + "</a> ";
+
+ if (e.extract) {
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ template.replace(/\[(-?\d)\]/g, function (_, i) {
+ return (parseInt(e.line) + parseInt(i)) || '';
+ }).replace(/\{(\d)\}/g, function (_, i) {
+ return e.extract[parseInt(i)] || '';
+ }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+ e.extract[1].slice(e.column) + '</span>');
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #ee4444;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.ctx {',
+ 'color: #dd4444;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless114minjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.4.min.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.4.min.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.4.min.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.4
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+//
+// LESS - Leaner CSS v1.1.4
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function u(a,b){var c="less-error-message:"+o(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p><a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+":</p>"+e.replace(/\[(-?\d)\]/g,function(b,c){return parseInt(a.line)+parseInt(c)||""}).replace(/\{(\d)\}/g,function(b,c){return a.extract[parseInt(c)]||"&q
uot;}).replace(/\{current\}/,a.extract[1].slice(0,a.column)+'<span class="error">'+a.extract[1].slice(a.column)+"</span>")),f.innerHTML=h,p([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #ee4444;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.ctx {","color: #dd4444;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","
;color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=setInterval(function(){document.body&&(document.getElementById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}function t(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: &quo
t;+a)}function s(a){return a&&a.parentNode.removeChild(a)}function r(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){t("browser doesn't support AJAX.");return null}}function q(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var g=r(),h=f?!1:d.async;typeof g.overrideMimeType=="function"&&g.overrideMimeType("text/css"),g.open("GET",a,h),g.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),g.send(null),f?g.status===0?c(g.responseText):e(g.status,a):h?g.onreadystatechange=function(){g.readyState==4&&i(g,c,e)}:i(g,c,e)}function p(a,b,c){var d,e=b.href?b.href.replace(/\?.*$/,""):"",f="less:"+(b.title||o(e));(d=document.getElementById(f))===null&
&(d=document.createElement("style"),d.type="text/css",d.media=b.media||"screen",d.id=f,document.getElementsByTagName("head")[0].appendChild(d));if(d.styleSheet)try{d.styleSheet.cssText=a}catch(h){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(a){d.childNodes.length>0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&g&&(t("saving "+e+" to cache."),g.setItem(e,a),g.setItem(e+":timestamp",c))}function o(a){return a.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\?.*$/,"").replace(/\.[^\.\/]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function n(b,c,e,f){var h=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/,""),j=g&&g.getItem(i),k=g&&g.getItem(i+":ti
mestamp"),l={css:j,timestamp:k};/^(https?|file):/.test(i)||(i.charAt(0)=="/"?i=a.location.protocol+"//"+a.location.host+i:i=h.slice(0,h.lastIndexOf("/")+1)+i),q(b.href,b.type,function(a,g){if(!e&&l&&g&&(new Date(g)).valueOf()===(new Date(l.timestamp)).valueOf())p(l.css,b),c(null,b,{local:!0,remaining:f});else try{(new d.Parser({optimization:d.optimization,paths:[i.replace(/[\w\.-]+$/,"")],mime:b.type})).parse(a,function(a,d){if(a)return u(a,i);try{c(d,b,{local:!1,lastModified:g,remaining:f}),s(document.getElementById("less-error-message:"+o(i)))}catch(a){u(a,i)}})}catch(h){u(h,i)}},function(a,b){throw new Error("Couldn't load "+b+" ("+a+")")})}function m(a,b){for(var c=0;c<d.sheets.length;c++)n(d.sheets[c],a,b,d.sheets.length-(c+1))}function l(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(j)&&(new d.Parser).p
arse(a[b].innerHTML||"",function(c,d){a[b].type="text/css",a[b].innerHTML=d.toCSS()})}function c(b){return a.less[b.split("/")[1]]}Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d<c;d++)d in this&&a.call(b,this[d],d,this)}),Array.prototype.map||(Array.prototype.map=function(a){var b=this.length>>>0,c=Array(b),d=arguments[1];for(var e=0;e<b;e++)e in this&&(c[e]=a.call(d,this[e],e,this));return c}),Array.prototype.filter||(Array.prototype.filter=function(a){var b=[],c=arguments[1];for(var d=0;d<this.length;d++)a.call(c,this[d])&&b.push(this[d]);return b}),Array.prototype.reduce||(Array.prototype.reduce=function(a){var b=this.length>>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.leng
th>=2)var d=arguments[1];else do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0);for(;c<b;c++)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){var b=this.length,c=arguments[1]||0;if(!b)return-1;if(c>=b)return-1;c<0&&(c+=b);for(;c<b;c++){if(!Object.prototype.hasOwnProperty.call(this,c))continue;if(a===this[c])return c}return-1}),Object.keys||(Object.keys=function(a){var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}),String.prototype.trim||(String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")});var d,e;typeof a=="undefined"?(d=exports,e=c("less/tree")):(typeof a.less=="undefined"&&(a.less={}),d=a.less,e=a.less.tree={}),d.Parser=function(a){function t(a){return typeof a=="string"?b.charAt(c)===a:a.test(j[f])?
!0:!1}function s(a){var d,e,g,h,i,m,n,o;if(a instanceof Function)return a.call(l.parsers);if(typeof a=="string")d=b.charAt(c)===a?a:null,g=1,r();else{r();if(d=a.exec(j[f]))g=d[0].length;else return null}if(d){o=c+=g,m=c+j[f].length-g;while(c<m){h=b.charCodeAt(c);if(h!==32&&h!==10&&h!==9)break;c++}j[f]=j[f].slice(g+(c-o)),k=c,j[f].length===0&&f<j.length-1&&f++;return typeof d=="string"?d:d.length===1?d[0]:d}}function r(){c>k&&(j[f]=j[f].slice(c-k),k=c)}function q(){j[f]=g,c=h,k=c}function p(){g=j[f],h=c,k=c}var b,c,f,g,h,i,j,k,l,m=this,n=function(){},o=this.imports={paths:a&&a.paths||[],queue:[],files:{},mime:a&&a.mime,push:function(b,c){var e=this;this.queue.push(b),d.Parser.importer(b,this.paths,function(a){e.queue.splice(e.queue.indexOf(b),1),e.files[b]=a,c(a),e.queue.length===0&&n()},a)}};this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.e
nv.filename=this.env.filename||null;return l={imports:o,parse:function(d,g){var h,l,m,o,p,q,r=[],t,u=null;c=f=k=i=0,j=[],b=d.replace(/\r\n/g,"\n"),j=function(c){var d=0,e=/[^"'`\{\}\/\(\)]+/g,f=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,g=0,h,i=c[0],j,k;for(var l=0,m,n;l<b.length;l++){e.lastIndex=l,(h=e.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0])),m=b.charAt(l),f.lastIndex=l,!k&&!j&&m==="/"&&(n=b.charAt(l+1),(n==="/"||n==="*")&&(h=f.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0]),m=b.charAt(l)));if(m==="{"&&!k&&!j)g++,i.push(m);else if(m==="}"&&!k&&!j)g--,i.push(m),c[++d]=i=[];else if(m==="("&&!k&&!j)i.push(m),j=!0;else if(m===")"&&!k&&j)i.push(m),j=!1;else{if(m==='"'||m==="'"||m==="`")k?k=k===m?!1:k:k=m;i.push(m)}}if(g>0)throw{type:&q
uot;Syntax",message:"Missing closing `}`",filename:a.filename};return c.map(function(a){return a.join("")})}([[]]),h=new e.Ruleset([],s(this.parsers.primary)),h.root=!0,h.toCSS=function(c){var d,f,g;return function(g,h){function n(a){return a?(b.slice(0,a).match(/\n/g)||"").length:null}var i=[];g=g||{},typeof h=="object"&&!Array.isArray(h)&&(h=Object.keys(h).map(function(a){var b=h[a];b instanceof e.Value||(b instanceof e.Expression||(b=new e.Expression([b])),b=new e.Value([b]));return new e.Rule("@"+a,b,!1,0)}),i=[new e.Ruleset(null,h)]);try{var j=c.call(this,{frames:i}).toCSS([],{compress:g.compress||!1})}catch(k){f=b.split("\n"),d=n(k.index);for(var l=k.index,m=-1;l>=0&&b.charAt(l)!=="\n";l--)m++;throw{type:k.type,message:k.message,filename:a.filename,index:k.index,line:typeof d=="number"?d+1:null,callLine:k.call&&n(k.call)+1,callExtract:f[n(k.call)],stack:k.sta
ck,column:m,extract:[f[d-1],f[d],f[d+1]]}}return g.compress?j.replace(/(\s)+/g,"$1"):j}}(h.eval);if(c<b.length-1){c=i,q=b.split("\n"),p=(b.slice(0,c).match(/\n/g)||"").length+1;for(var v=c,w=-1;v>=0&&b.charAt(v)!=="\n";v--)w++;u={name:"ParseError",message:"Syntax Error on line "+p,index:c,filename:a.filename,line:p,column:w,extract:[q[p-2],q[p-1],q[p]]}}this.imports.queue.length>0?n=function(){g(u,h)}:g(u,h)},parsers:{primary:function(){var a,b=[];while((a=s(this.mixin.definition)||s(this.rule)||s(this.ruleset)||s(this.mixin.call)||s(this.comment)||s(this.directive))||s(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(b.charAt(c)==="/"){if(b.charAt(c+1)==="/")return new e.Comment(s(/^\/\/.*/),!0);if(a=s(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new e.Comment(a)}},entities:{quoted:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)=
=='"'||b.charAt(d)==="'"){f&&s("~");if(a=s(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new e.Quoted(a[0],a[1]||a[2],f)}},keyword:function(){var a;if(a=s(/^[A-Za-z-]+/))return new e.Keyword(a)},call:function(){var a,b,d=c;if(!!(a=/^([\w-]+|%)\(/.exec(j[f]))){a=a[1].toLowerCase();if(a==="url")return null;c+=a.length;if(a==="alpha")return s(this.alpha);s("("),b=s(this.entities.arguments);if(!s(")"))return;if(a)return new e.Call(a,b,d)}},arguments:function(){var a=[],b;while(b=s(this.expression)){a.push(b);if(!s(","))break}return a},literal:function(){return s(this.entities.dimension)||s(this.entities.color)||s(this.entities.quoted)},url:function(){var a;if(b.charAt(c)==="u"&&!!s(/^url\(/)){a=s(this.entities.quoted)||s(this.entities.variable)||s(this.entities.dataURI)||s(/^[-\w%@$\/.&=:;#+?~]+/)||"";if(!s(")"))throw new Error("mi
ssing closing ) for url()");return new e.URL(a.value||a.data||a instanceof e.Variable?a:new e.Anonymous(a),o.paths)}},dataURI:function(){var a;if(s(/^data:/)){a={},a.mime=s(/^[^\/]+\/[^,;)]+/)||"",a.charset=s(/^;\s*charset=[^,;)]+/)||"",a.base64=s(/^;\s*base64/)||"",a.data=s(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var a,d=c;if(b.charAt(c)==="@"&&(a=s(/^@@?[\w-]+/)))return new e.Variable(a,d)},color:function(){var a;if(b.charAt(c)==="#"&&(a=s(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new e.Color(a[1])},dimension:function(){var a,d=b.charCodeAt(c);if(!(d>57||d<45||d===47))if(a=s(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new e.Dimension(a[1],a[2])},javascript:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)==="`"){f&&s("~");if(a=s(/^`([^`]*)`/))return new e.JavaScript(a[1],c,f)}}},variable:funct
ion(){var a;if(b.charAt(c)==="@"&&(a=s(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!!t(/^[@\w.%-]+\/[@\w.-]+/)&&(a=s(this.entity))&&s("/")&&(b=s(this.entity)))return new e.Shorthand(a,b)},mixin:{call:function(){var a=[],d,f,g,h=c,i=b.charAt(c);if(i==="."||i==="#"){while(d=s(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))a.push(new e.Element(f,d)),f=s(">");s("(")&&(g=s(this.entities.arguments))&&s(")");if(a.length>0&&(s(";")||t("}")))return new e.mixin.Call(a,g,h)}},definition:function(){var a,d=[],f,g,h,i;if(!(b.charAt(c)!=="."&&b.charAt(c)!=="#"||t(/^[^{]*(;|})/)))if(f=s(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=f[1];while(h=s(this.entities.variable)||s(this.entities.literal)||s(this.entities.keyword)){if(h instanceof e.Variable)if(s(":"))if
(i=s(this.expression))d.push({name:h.name,value:i});else throw new Error("Expected value");else d.push({name:h.name});else d.push({value:h});if(!s(","))break}if(!s(")"))throw new Error("Expected )");g=s(this.block);if(g)return new e.mixin.Definition(a,d,g)}}},entity:function(){return s(this.entities.literal)||s(this.entities.variable)||s(this.entities.url)||s(this.entities.call)||s(this.entities.keyword)||s(this.entities.javascript)||s(this.comment)},end:function(){return s(";")||t("}")},alpha:function(){var a;if(!!s(/^\(opacity=/i))if(a=s(/^\d+/)||s(this.entities.variable)){if(!s(")"))throw new Error("missing closing ) for alpha()");return new e.Alpha(a)}},element:function(){var a,b,c;c=s(this.combinator),a=s(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||s("*")||s(this.attribute)||s(/^\([^)@]+\)/)||s(/^(?:\d*\.)?\d+%/);if(a)return new e.Element(c,a);if(c.value&&c.va
lue[0]==="&")return new e.Element(c,null)},combinator:function(){var a,d=b.charAt(c);if(d===">"||d==="+"||d==="~"){c++;while(b.charAt(c)===" ")c++;return new e.Combinator(d)}if(d==="&"){a="&",c++,b.charAt(c)===" "&&(a="& ");while(b.charAt(c)===" ")c++;return new e.Combinator(a)}if(d===":"&&b.charAt(c+1)===":"){c+=2;while(b.charAt(c)===" ")c++;return new e.Combinator("::")}return b.charAt(c-1)===" "?new e.Combinator(" "):new e.Combinator(null)},selector:function(){var a,d,f=[],g,h;while(d=s(this.element)){g=b.charAt(c),f.push(d);if(g==="{"||g==="}"||g===";"||g===",")break}if(f.length>0)return new e.Selector(f)},tag:function(){return s(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||s("*")},attribute:function(){var a="",b,c,d;if(!!s("[")){
if(b=s(/^[a-zA-Z-]+/)||s(this.entities.quoted))(d=s(/^[|~*$^]?=/))&&(c=s(this.entities.quoted)||s(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!s("]"))return;if(a)return"["+a+"]"}},block:function(){var a;if(s("{")&&(a=s(this.primary))&&s("}"))return a},ruleset:function(){var a=[],b,d,g;p();if(g=/^([.#:% \w-]+)[\s\n]*\{/.exec(j[f]))c+=g[0].length-1,a=[new e.Selector([new e.Element(null,g[1])])];else while(b=s(this.selector)){a.push(b),s(this.comment);if(!s(","))break;s(this.comment)}if(a.length>0&&(d=s(this.block)))return new e.Ruleset(a,d);i=c,q()},rule:function(){var a,d,g=b.charAt(c),k,l;p();if(g!=="."&&g!=="#"&&g!=="&")if(a=s(this.variable)||s(this.property)){a.charAt(0)!="@"&&(l=/^([^@+\/'"*`(;{}-]*);/.exec(j[f]))?(c+=l[0].length-1,d=new e.Anonymous(l[1])):a==="font"?d=s(this.font):d
=s(this.value),k=s(this.important);if(d&&s(this.end))return new e.Rule(a,d,k,h);i=c,q()}},"import":function(){var a;if(s(/^@import\s+/)&&(a=s(this.entities.quoted)||s(this.entities.url))&&s(";"))return new e.Import(a,o)},directive:function(){var a,d,f,g;if(b.charAt(c)==="@"){if(d=s(this["import"]))return d;if(a=s(/^@media|@page/)||s(/^@(?:-webkit-)?keyframes/)){g=(s(/^[^{]+/)||"").trim();if(f=s(this.block))return new e.Directive(a+" "+g,f)}else if(a=s(/^@[-a-z]+/))if(a==="@font-face"){if(f=s(this.block))return new e.Directive(a,f)}else if((d=s(this.entity))&&s(";"))return new e.Directive(a,d)}},font:function(){var a=[],b=[],c,d,f,g;while(g=s(this.shorthand)||s(this.entity))b.push(g);a.push(new e.Expression(b));if(s(","))while(g=s(this.expression)){a.push(g);if(!s(","))break}return new e.Value(a)},value:function(){var a,b=[],c;while(a=s(this.expression))
{b.push(a);if(!s(","))break}if(b.length>0)return new e.Value(b)},important:function(){if(b.charAt(c)==="!")return s(/^! *important/)},sub:function(){var a;if(s("(")&&(a=s(this.expression))&&s(")"))return a},multiplication:function(){var a,b,c,d;if(a=s(this.operand)){while((c=s("/")||s("*"))&&(b=s(this.operand)))d=new e.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,d,f,g;if(a=s(this.multiplication)){while((f=s(/^[-+]\s+/)||b.charAt(c-1)!=" "&&(s("+")||s("-")))&&(d=s(this.multiplication)))g=new e.Operation(f,[g||a,d]);return g||a}},operand:function(){var a,d=b.charAt(c+1);b.charAt(c)==="-"&&(d==="@"||d==="(")&&(a=s("-"));var f=s(this.sub)||s(this.entities.dimension)||s(this.entities.color)||s(this.entities.variable)||s(this.entities.call);return a?new e.Operation("*",[new e
.Dimension(-1),f]):f},expression:function(){var a,b,c=[],d;while(a=s(this.addition)||s(this.entity))c.push(a);if(c.length>0)return new e.Expression(c)},property:function(){var a;if(a=s(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}},typeof a!="undefined"&&(d.Parser.importer=function(a,b,c,d){a.charAt(0)!=="/"&&b.length>0&&(a=b[0]+a),n({href:a,title:a,type:d.mime},c,!0)}),function(a){function d(a){return Math.min(1,Math.max(0,a))}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function
(a,b,d,e){function h(a){a=a<0?a+1:a>1?a-1:a;return a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(Math.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();e.s+=c.value/100,e.s=d(e.s);return b(e)},desaturate:function(a,c){var e=a.toHSL();e.s-=c.value/100,e.s=d(e.s);return b(e)},lighten:function(a,c){var e=a.toHSL();e.l+=c.value/100,e.l=d(e.l);return b(e)},darken:function(a,c){var e=a.toHSL();e.l-=c.value/100,e.l=d(e.l);return b(e)},fadein:function(a,c){var e=a.toHSL();e.a+=c.value/100,e.a=d(e.a);return b(e)},fadeout:function(a,c){var e=a.toHSL();e.a-=c.value/1
00,e.a=d(e.a);return b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;d.h=e<0?360+e:e;return b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e<c.length;e++)d=d.replace(/%[sda]/i,function(a){var b=a.match(/s/i)?c[e].value:c[e].toCSS();return a.match(/[A-Z]$/)?encodeURIComponent(b):b});d=d.replace(/%%
/g,"%");return new a.Quoted('"'+d+'"',d)},round:function(b){if(b instanceof a.Dimension)return new a.Dimension(Math.round(c(b)),b.unit);if(typeof b=="number")return Math.round(b);throw{error:"RuntimeError",message:"math functions take numbers as parameters"}}}}(c("less/tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(a){this.value.eval&&(this.value=this.value.eval(a));return this}}}(c("less/tree")),function(a){a.Anonymous=function(a){this.value=a.value||a},a.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this}}}(c("less/tree")),function(a){a.Call=function(a,b,c){this.name=a,this.args=b,this.index=c},a.Call.prototype={eval:function(b){var c=this.args.map(function(a){return a.eval(b)});if(!(this.name in a.functions))
return new a.Anonymous(this.name+"("+c.map(function(a){return a.toCSS()}).join(", ")+")");try{return a.functions[this.name].apply(a.functions,c)}catch(d){throw{message:"error evaluating function `"+this.name+"`",index:this.index}}},toCSS:function(a){return this.eval(a).toCSS()}}}(c("less/tree")),function(a){a.Color=function(a,b){Array.isArray(a)?this.rgb=a:a.length==6?this.rgb=a.match(/.{2}/g).map(function(a){return parseInt(a,16)}):a.length==8?(this.alpha=parseInt(a.substring(0,2),16)/255,this.rgb=a.substr(2).match(/.{2}/g).map(function(a){return parseInt(a,16)})):this.rgb=a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha=typeof b=="number"?b:1},a.Color.prototype={eval:function(){return this},toCSS:function(){return this.alpha<1?"rgba("+this.rgb.map(function(a){return Math.round(a)}).concat(this.alpha).join(", ")+")":"#"+this.rgb.map(function(a){
a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16);return a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);switch(e){case a:g=(b-c)/j+(b<c?6:0);break;case b:g=(c-a)/j+2;break;case c:g=(a-b)/j+4}g/=6}return{h:g*360,s:h,l:i,a:d}}}}(c("less/tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("less/tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){retur
n new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)}}}(c("less/tree")),function(a){a.Directive=function(b,c){this.name=b,Array.isArray(c)?this.ruleset=new a.Ruleset([],c):this.value=c},a.Directive.prototype={toCSS:function(a,b){if(this.ruleset){this.ruleset.root=!0;return this.name+(b.compress?"{":" {\n ")+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n ")+(b.compress?"}":"\n}\n")}return this.name+" "+this.value.toCSS()+";\n"},eval:function(a){a.frames.unshift(this),this.ruleset=this.ruleset&&this.ruleset.eval(a),a.frames.shift();return this},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rul
esets.apply(this.ruleset)}}}(c("less/tree")),function(a){a.Element=function(b,c){this.combinator=b instanceof a.Combinator?b:new a.Combinator(b),this.value=c?c.trim():""},a.Element.prototype.toCSS=function(a){return this.combinator.toCSS(a||{})+this.value},a.Combinator=function(a){a===" "?this.value=" ":a==="& "?this.value="& ":this.value=a?a.trim():""},a.Combinator.prototype.toCSS=function(a){return{"":""," ":" ","&":"","& ":" ",":":" :","::":"::","+":a.compress?"+":" + ","~":a.compress?"~":" ~ ",">":a.compress?">":" > "}[this.value]}}(c("less/tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?n
ew a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(" ")}}}(c("less/tree")),function(a){a.Import=function(b,c){var d=this;this._path=b,b instanceof a.Quoted?this.path=/\.(le?|c)ss$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value||b.value,this.css=/css$/.test(this.path),this.css||c.push(this.path,function(a){if(!a)throw new Error("Error parsing "+d.path);d.root=a})},a.Import.prototype={toCSS:function(){return this.css?"@import "+this._path.toCSS()+";\n":""},eval:function(b){var c;if(this.css)return this;c=new a.Ruleset(null,this.root.rules.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));return c.rules}}}(c("less/tree")),function(a){a.JavaScript=func
tion(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify((new a.Variable("@"+e,d.index)).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: `"+f+"`",index:this.index}}for(var h in b.frames[0].variables())e[h.slice(1)]={value:b.frames[0].variables()[h].value,toJS:function(){return this.value.eval(b).toCSS()}};try{c=f.call(e)}catch(g){throw{message:"JavaScript evaluation error: '"+g.name+": "+g.message+"'",index:this.index}}return typeof c=="string"?new a.Quoted('"'+c+'"',c,this.escaped,this.index):Array.isArray(c)?new a.Anonymous(c.join(", ")):new a.Anonymous(c)}}}(c("less/tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={eval:function(){return this},toCSS:fun
ction(){return this.value}}}(c("less/tree")),function(a){a.mixin={},a.mixin.Call=function(b,c,d){this.selector=new a.Selector(b),this.arguments=c,this.index=d},a.mixin.Call.prototype={eval:function(a){var b,c,d=[],e=!1;for(var f=0;f<a.frames.length;f++)if((b=a.frames[f].find(this.selector)).length>0){c=this.arguments&&this.arguments.map(function(b){return b.eval(a)});for(var g=0;g<b.length;g++)if(b[g].match(c,a))try{Array.prototype.push.apply(d,b[g].eval(a,this.arguments).rules),e=!0}catch(h){throw{message:h.message,index:h.index,stack:h.stack,call:this.index}}if(e)return d;throw{message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(a){return a.toCSS()}).join(", ")+")`",index:this.index}}throw{message:this.selector.toCSS().trim()+" is undefined",index:this.index}}},a.mixin.Definition=function(b,c,d){this.name=b,this.selectors=[new a.Selector([new a.Ele
ment(null,b)])],this.params=c,this.arity=c.length,this.rules=d,this._lookups={},this.required=c.reduce(function(a,b){return!b.name||b.name&&!b.value?a+1:a},0),this.parent=a.Ruleset.prototype,this.frames=[]},a.mixin.Definition.prototype={toCSS:function(){return""},variable:function(a){return this.parent.variable.call(this,a)},variables:function(){return this.parent.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},eval:function(b,c){var d=new a.Ruleset(null,[]),e,f=[];for(var g=0,h;g<this.params.length;g++)if(this.params[g].name)if(h=c&&c[g]||this.params[g].value)d.rules.unshift(new a.Rule(this.params[g].name,h.eval(b)));else throw{message:"wrong number of arguments for "+this.name+" ("+c.length+" for "+this.arity+")"};for(var g=0;g<Math.max(this.params.length,c&&c.length);g++)f.push(c[g]||this.params[g].value)
;d.rules.unshift(new a.Rule("@arguments",(new a.Expression(f)).eval(b)));return(new a.Ruleset(null,this.rules.slice(0))).eval({frames:[this,d].concat(this.frames,b.frames)})},match:function(a,b){var c=a&&a.length||0,d;if(c<this.required)return!1;if(this.required>0&&c>this.params.length)return!1;d=Math.min(c,this.arity);for(var e=0;e<d;e++)if(!this.params[e].name&&a[e].eval(b).toCSS()!=this.params[e].value.eval(b).toCSS())return!1;return!0}}}(c("less/tree")),function(a){a.Operation=function(a,b){this.op=a.trim(),this.operands=b},a.Operation.prototype.eval=function(b){var c=this.operands[0].eval(b),d=this.operands[1].eval(b),e;if(c instanceof a.Dimension&&d instanceof a.Color)if(this.op==="*"||this.op==="+")e=d,d=c,c=e;else throw{name:"OperationError",message:"Can't substract or divide a color from a number"};return c.operate(this.op,d)},a.operate=function(a,b,c){switch(a){case"
;+":return b+c;case"-":return b-c;case"*":return b*c;case"/":return b/c}}}(c("less/tree")),function(a){a.Quoted=function(a,b,c,d){this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d},a.Quoted.prototype={toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(b){var c=this,d=this.value.replace(/`([^`]+)`/g,function(d,e){return(new a.JavaScript(e,c.index,!0)).eval(b).value}).replace(/@\{([\w-]+)\}/g,function(d,e){var f=(new a.Variable("@"+e,c.index)).eval(b);return f.value||f.toCSS()});return new a.Quoted(this.quote+d+this.quote,d,this.escaped,this.index)}}}(c("less/tree")),function(a){a.Rule=function(b,c,d,e){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.index=e,b.charAt(0)==="@"?this.variable=!0:this.variable=!1},a.Rule.prototype.toCSS=function(a){return this.variable?&q
uot;":this.name+(a.compress?":":": ")+this.value.toCSS(a)+this.important+";"},a.Rule.prototype.eval=function(b){return new a.Rule(this.name,this.value.eval(b),this.important,this.index)},a.Shorthand=function(a,b){this.a=a,this.b=b},a.Shorthand.prototype={toCSS:function(a){return this.a.toCSS(a)+"/"+this.b.toCSS(a)},eval:function(){return this}}}(c("less/tree")),function(a){a.Ruleset=function(a,b){this.selectors=a,this.rules=b,this._lookups={}},a.Ruleset.prototype={eval:function(b){var c=new a.Ruleset(this.selectors,this.rules.slice(0));c.root=this.root,b.frames.unshift(c);if(c.root)for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Definition&&(c.rules[d].frames=b.frames.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Call&&Array
.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0,e;d<c.rules.length;d++)e=c.rules[d],e instanceof a.mixin.Definition||(c.rules[d]=e.eval?e.eval(b):e);b.frames.shift();return c},match:function(a){return!a||a.length===0},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(b,c){c instanceof a.Rule&&c.variable===!0&&(b[c.name]=c);return b},{})},variable:function(a){return this.variables()[a]},rulesets:function(){return this._rulesets?this._rulesets:this._rulesets=this.rules.filter(function(b){return b instanceof a.Ruleset||b instanceof a.mixin.Definition})},find:function(b,c){c=c||this;var d=[],e,f,g=b.toCSS();if(g in this._lookups)return this._lookups[g];this.rulesets().forEach(function(e){if(e!==c)for(var g=0;g<e.selectors.length;g++)if(f=b.match(e.selectors[g])){b.elements.length>1?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}});retur
n this._lookups[g]=d},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;this.root||(b.length===0?g=this.selectors.map(function(a){return[a]}):this.joinSelectors(g,b,this.selectors));for(var j=0;j<this.rules.length;j++)i=this.rules[j],i.rules||i instanceof a.Directive?f.push(i.toCSS(g,c)):i instanceof a.Comment?i.silent||(this.root?f.push(i.toCSS(c)):e.push(i.toCSS(c))):i.toCSS&&!i.variable?e.push(i.toCSS(c)):i.value&&!i.variable&&e.push(i.value.toString());f=f.join(""),this.root?d.push(e.join(c.compress?"":"\n")):e.length>0&&(h=g.map(function(a){return a.map(function(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":g.length>3?",\n":", "),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f);return d.join("")+(c.compress?"\n":"")}
,joinSelectors:function(a,b,c){for(var d=0;d<c.length;d++)this.joinSelector(a,b,c[d])},joinSelector:function(b,c,d){var e=[],f=[],g=[],h=[],i=!1,j;for(var k=0;k<d.elements.length;k++)j=d.elements[k],j.combinator.value[0]==="&"&&(i=!0),i?h.push(j):g.push(j);i||(h=g,g=[]),g.length>0&&e.push(new a.Selector(g)),h.length>0&&f.push(new a.Selector(h));for(var l=0;l<c.length;l++)b.push(e.concat(c[l]).concat(f))}}}(c("less/tree")),function(a){a.Selector=function(a){this.elements=a,this.elements[0].combinator.value===""&&(this.elements[0].combinator.value=" ")},a.Selector.prototype.match=function(a){return this.elements[0].value===a.elements[0].value?!0:!1},a.Selector.prototype.toCSS=function(a){return this._css?this._css:this._css=this.elements.map(function(b){return typeof b=="string"?" "+b.trim():b.toCSS(a)}).join("")}}(c("less/tree")),function(b){b.URL=functio
n(b,c){b.data?this.attrs=b:(!/^(?:https?:\/|file:\/|data:\/)?\//.test(b.value)&&c.length>0&&typeof a!="undefined"&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs
+.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("less/tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("less/tree")),function(a){a.Variable=function(a,b){this.name=a,this.index=b},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{message:"variable "+e+" is undefined",index:this.index}}}}(c("less/tree")),c("l
ess/tree").find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null},c("less/tree").jsify=function(a){return Array.isArray(a.value)&&a.value.length>1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)};var f=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||f?"development":"production"),d.async=!1,d.poll=d.poll||(f?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&
;m(function(a,b,c){a&&p(a.toCSS(),b,c.lastModified)})},d.poll)):d.optimization=3;var g;try{g=typeof a.localStorage=="undefined"?null:a.localStorage}catch(h){g=null}var i=document.getElementsByTagName("link"),j=/^text\/(x-)?less$/;d.sheets=[];for(var k=0;k<i.length;k++)(i[k].rel==="stylesheet/less"||i[k].rel.match(/stylesheet/)&&i[k].type.match(j))&&d.sheets.push(i[k]);d.refresh=function(a){var b,c;b=c=new Date,m(function(a,d,e){e.local?t("loading "+d.href+" from cache."):(t("parsed "+d.href+" successfully."),p(a.toCSS(),d,e.lastModified)),t("css for "+d.href+" generated in "+(new Date-c)+"ms"),e.remaining===0&&t("css generated in "+(new Date-b)+"ms"),c=new Date},a),l()},d.refreshStyles=l,d.refresh(d.env==="development")})(window)
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless115js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.5.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.5.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.5.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2805 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.5
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+ // Rhino
+ // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+ less = {};
+ tree = less.tree = {};
+ less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+ // Node.js
+ less = exports,
+ tree = require('./tree');
+ less.mode = 'node';
+} else {
+ // Browser
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+ less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ mime: env && env.mime, // MIME type of .less files
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (root) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+
+ callback(root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ chunks = [];
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam,
+ inString;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = i;
+
+ if (!inString && !inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ if (c === '{' && !inString && !inParam) { level ++;
+ chunk.push(c);
+ } else if (c === '}' && !inString && !inParam) { level --;
+ chunk.push(c);
+ chunks[++j] = chunk = [];
+ } else if (c === '(' && !inString && !inParam) {
+ chunk.push(c);
+ inParam = true;
+ } else if (c === ')' && !inString && inParam) {
+ chunk.push(c);
+ inParam = false;
+ } else {
+ if (c === '"' || c === "'" || c === '`') {
+ if (! inString) {
+ inString = c;
+ } else {
+ inString = inString === c ? false : inString;
+ }
+ }
+ chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ throw {
+ type: 'Syntax',
+ message: "Missing closing `}`",
+ filename: env.filename
+ };
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [];
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ lines = input.split('\n');
+ line = getLine(e.index);
+
+ for (var n = e.index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ throw {
+ type: e.type,
+ message: e.message,
+ filename: env.filename,
+ index: e.index,
+ line: typeof(line) === 'number' ? line + 1 : null,
+ callLine: e.call && (getLine(e.call) + 1),
+ callExtract: lines[getLine(e.call)],
+ stack: e.stack,
+ column: column,
+ extract: [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ]
+ };
+ }
+ if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+
+ function getLine(index) {
+ return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ name: "ParseError",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+ if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) { return new(tree.Keyword)(k) }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args, index = i;
+
+ if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args, index) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+ if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e, i));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value;
+
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ while (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ if (value = $(this.expression)) {
+ params.push({ name: param.name, value: value });
+ } else {
+ throw new(Error)("Expected value");
+ }
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ if (! $(',')) { break }
+ }
+ if (! $(')')) throw new(Error)("Expected )");
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset);
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^\(opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c;
+
+ c = $(this.combinator);
+ e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+ $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+ if (e) { return new(tree.Element)(c, e, i) }
+
+ if (c.value && c.value.charAt(0) === '&') {
+ return new(tree.Element)(c, null, i);
+ }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === '&') {
+ match = '&';
+ i++;
+ if(input.charAt(i) === ' ') {
+ match = '& ';
+ }
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(match);
+ } else if (c === ':' && input.charAt(i + 1) === ':') {
+ i += 2;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)('::');
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url)) &&
+ $(';')) {
+ return new(tree.Import)(path, imports);
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import'])) {
+ return value;
+ } else if (name = $(/^@media|@page/) || $(/^@(?:-webkit-|-moz-)?keyframes/)) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (path.charAt(0) !== '/' && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fade: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a = amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math.round(number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math.round(n);
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "math functions take numbers as parameters"
+ };
+ }
+ },
+ argb: function (color) {
+ return new(tree.Anonymous)(color.toARGB());
+
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+ this.name = name;
+ this.args = args;
+ this.index = index;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ try {
+ return tree.functions[this.name].apply(tree.functions, args);
+ } catch (e) {
+ throw { message: "error evaluating function `" + this.name + "`",
+ index: this.index };
+ }
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ },
+ toARGB: function () {
+ var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+ return '#' + argb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+ this.name = name;
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+ this.value = value ? value.trim() : "";
+ this.index = index;
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else if (value === '& ') {
+ this.value = '& ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ '& ' : ' ',
+ ':' : ' :',
+ '::': '::',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(' ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+ var that = this;
+
+ this._path = path;
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css(\?.*)?$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (root) {
+ if (! root) {
+ throw new(Error)("Error parsing " + that.path);
+ }
+ that.root = root;
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function () {
+ if (this.css) {
+ return "@import " + this._path.toCSS() + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset;
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return ruleset.rules;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index };
+ }
+ }
+ }
+ throw { message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ eval: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+ for (var i = 0, val; i < this.params.length; i++) {
+ if (this.params[i].name) {
+ if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+ } else {
+ throw { message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len;
+
+ if (argsLength < this.required) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return v.value || v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + ";";
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+ ruleset.root = this.root;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > rule.selectors[j].elements.length) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ this.joinSelectors( paths, context, this.selectors );
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ },
+
+ joinSelectors: function (paths, context, selectors) {
+ for (var s = 0; s < selectors.length; s++) {
+ this.joinSelector(paths, context, selectors[s]);
+ }
+ },
+
+ joinSelector: function (paths, context, selector) {
+ var before = [], after = [], beforeElements = [],
+ afterElements = [], hasParentSelector = false, el;
+
+ for (var i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ if (el.combinator.value.charAt(0) === '&') {
+ hasParentSelector = true;
+ }
+ if (hasParentSelector) afterElements.push(el);
+ else beforeElements.push(el);
+ }
+
+ if (! hasParentSelector) {
+ afterElements = beforeElements;
+ beforeElements = [];
+ }
+
+ if (beforeElements.length > 0) {
+ before.push(new(tree.Selector)(beforeElements));
+ }
+
+ if (afterElements.length > 0) {
+ after.push(new(tree.Selector)(afterElements));
+ }
+
+ for (var c = 0; c < context.length; c++) {
+ paths.push(before.concat(context[c]).concat(after));
+ }
+ }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ var len = this.elements.length,
+ olen = other.elements.length,
+ max = Math.min(len, olen);
+
+ if (len < olen) {
+ return false;
+ } else {
+ for (var i = 0; i < max; i++) {
+ if (this.elements[i].value !== other.elements[i].value) {
+ return false;
+ }
+ }
+ }
+ return true;
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (less.mode === 'browser' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { message: "variable " + name + " is undefined",
+ index: this.index };
+ }
+ }
+};
+
+})(require('../tree'));
+require('./tree').find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+require('./tree').jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:' ||
+ location.protocol === 'chrome:' ||
+ location.protocol === 'chrome-extension:' ||
+ location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (root, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (root, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+ var css = tree.toCSS();
+ var style = styles[i];
+ try {
+ style.innerHTML = css;
+ } catch (_) {
+ style.styleSheets.cssText = css;
+ }
+ style.type = 'text/css';
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^(https?|file):/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ css.media = sheet.media || 'screen';
+ css.id = id;
+ document.getElementsByTagName('head')[0].appendChild(css);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? false : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol) {
+ if (xhr.status === 0) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+
+ var template = ['<ul>',
+ '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+ '<li><label>[0]</label><pre>{current}</pre></li>',
+ '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+ '</ul>'].join('\n');
+
+ var elem = document.createElement('div'), timer, content;
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p><a href="' + href + '">' + href + "</a> ";
+
+ if (e.extract) {
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ template.replace(/\[(-?\d)\]/g, function (_, i) {
+ return (parseInt(e.line) + parseInt(i)) || '';
+ }).replace(/\{(\d)\}/g, function (_, i) {
+ return e.extract[parseInt(i)] || '';
+ }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+ e.extract[1].slice(e.column) + '</span>');
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #ee4444;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.ctx {',
+ 'color: #dd4444;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless115minjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.5.min.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.5.min.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.5.min.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.5
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function c(b){return a.less[b.split("/")[1]]}function l(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(j)&&(new d.Parser).parse(a[b].innerHTML||"",function(c,d){var e=d.toCSS(),f=a[b];try{f.innerHTML=e}catch(g){f.styleSheets.cssText=e}f.type="text/css"})}function m(a,b){for(var c=0;c<d.sheets.length;c++)n(d.sheets[c],a,b,d.sheets.length-(c+1))}function n(b,c,e,f){var h=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/,""),j=g&&g.getItem(i),k=g&&g.getItem(i+":timestamp"),l={css:j,timestamp:k};/^(https?|file):/.test(i)||(i.charAt(0)=="/"?i=a.location.protocol+"//"+a.location.host+i:i=h.slice(0,h.lastIndexOf("/")+1)+i),q(b.href,b.type,function(a,g){if(!e&&l&&g&&(new Date(g)).valueOf()===(new Date(l.timestamp)).valueOf())p(l.css,b),c(null,b,{local:!0,remaining:f});e
lse try{(new d.Parser({optimization:d.optimization,paths:[i.replace(/[\w\.-]+$/,"")],mime:b.type})).parse(a,function(a,d){if(a)return u(a,i);try{c(d,b,{local:!1,lastModified:g,remaining:f}),s(document.getElementById("less-error-message:"+o(i)))}catch(a){u(a,i)}})}catch(h){u(h,i)}},function(a,b){throw new Error("Couldn't load "+b+" ("+a+")")})}function o(a){return a.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\?.*$/,"").replace(/\.[^\.\/]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function p(a,b,c){var d,e=b.href?b.href.replace(/\?.*$/,""):"",f="less:"+(b.title||o(e));(d=document.getElementById(f))===null&&(d=document.createElement("style"),d.type="text/css",d.media=b.media||"screen",d.id=f,document.getElementsByTagName("head")[0].appendChild(d));if(d.styleSheet)try{d.style
Sheet.cssText=a}catch(h){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(a){d.childNodes.length>0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&g&&(t("saving "+e+" to cache."),g.setItem(e,a),g.setItem(e+":timestamp",c))}function q(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var g=r(),h=f?!1:d.async;typeof g.overrideMimeType=="function"&&g.overrideMimeType("text/css"),g.open("GET",a,h),g.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),g.send(null),f?g.status===0?c(g.responseText):e(g.status,a):h?g.onreadystatechange=function(){g.readyState==4&&i(g,c,e)}:i(g,c,e)}function r(){if(a.XMLHttpReques
t)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){return t("browser doesn't support AJAX."),null}}function s(a){return a&&a.parentNode.removeChild(a)}function t(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: "+a)}function u(a,b){var c="less-error-message:"+o(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p&
gt;<a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+":</p>"+e.replace(/\[(-?\d)\]/g,function(b,c){return parseInt(a.line)+parseInt(c)||""}).replace(/\{(\d)\}/g,function(b,c){return a.extract[parseInt(c)]||""}).replace(/\{current\}/,a.extract[1].slice(0,a.column)+'<span class="error">'+a.extract[1].slice(a.column)+"</span>")),f.innerHTML=h,p([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #ee4444;","padding: 4px 0;","margin: 0;","d
isplay: inline-block;","}",".less-error-message pre.ctx {","color: #dd4444;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=set
Interval(function(){document.body&&(document.getElementById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d<c;d++)d in this&&a.call(b,this[d],d,this)}),Array.prototype.map||(Array.prototype.map=function(a){var b=this.length>>>0,c=new Array(b),d=arguments[1];for(var e=0;e<b;e++)e in this&&(c[e]=a.call(d,this[e],e,this));return c}),Array.prototype.filter||(Array.prototype.filter=function(a){var b=[],c=arguments[1];for(var d=0;d<this.length;d++)a.call(c,this[d])&&b.push(this[d]);return b}),Array.prototype.reduce||(Array.prototype.reduce=function(a){var b=this.length>>>0,c=0;if(b===0&&argument
s.length===1)throw new TypeError;if(arguments.length>=2)var d=arguments[1];else do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0);for(;c<b;c++)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){var b=this.length,c=arguments[1]||0;if(!b)return-1;if(c>=b)return-1;c<0&&(c+=b);for(;c<b;c++){if(!Object.prototype.hasOwnProperty.call(this,c))continue;if(a===this[c])return c}return-1}),Object.keys||(Object.keys=function(a){var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}),String.prototype.trim||(String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")});var d,e;typeof environment=="object"&&{}.toString.call(environment)==="[object Environment]"?(d={},e=d.tree={},d.mode="rhino"):typeof a=="undefined"?(d=exports,e=c(&qu
ot;./tree"),d.mode="node"):(typeof a.less=="undefined"&&(a.less={}),d=a.less,e=a.less.tree={},d.mode="browser"),d.Parser=function(a){function p(){g=j[f],h=c,k=c}function q(){j[f]=g,c=h,k=c}function r(){c>k&&(j[f]=j[f].slice(c-k),k=c)}function s(a){var d,e,g,h,i,m,n,o;if(a instanceof Function)return a.call(l.parsers);if(typeof a=="string")d=b.charAt(c)===a?a:null,g=1,r();else{r();if(d=a.exec(j[f]))g=d[0].length;else return null}if(d){o=c+=g,m=c+j[f].length-g;while(c<m){h=b.charCodeAt(c);if(h!==32&&h!==10&&h!==9)break;c++}return j[f]=j[f].slice(g+(c-o)),k=c,j[f].length===0&&f<j.length-1&&f++,typeof d=="string"?d:d.length===1?d[0]:d}}function t(a){return typeof a=="string"?b.charAt(c)===a:a.test(j[f])?!0:!1}var b,c,f,g,h,i,j,k,l,m=this,n=function(){},o=this.imports={paths:a&&a.paths||[],queue:[],files:{},mime:a&&a.mime,push:function(b,c){var e=this;t
his.queue.push(b),d.Parser.importer(b,this.paths,function(a){e.queue.splice(e.queue.indexOf(b),1),e.files[b]=a,c(a),e.queue.length===0&&n()},a)}};return this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.filename=this.env.filename||null,l={imports:o,parse:function(d,g){var h,l,m,o,p,q,r=[],t,u=null;c=f=k=i=0,j=[],b=d.replace(/\r\n/g,"\n"),j=function(c){var d=0,e=/[^"'`\{\}\/\(\)]+/g,f=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,g=0,h,i=c[0],j,k;for(var l=0,m,n;l<b.length;l++){e.lastIndex=l,(h=e.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0])),m=b.charAt(l),f.lastIndex=l,!k&&!j&&m==="/"&&(n=b.charAt(l+1),(n==="/"||n==="*")&&(h=f.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0]),m=b.charAt(l)));if(m==="{"&&!k&&!j)g++,i.push(m);else if(m==="}"&&!k&&!j)g--,i.push(m
),c[++d]=i=[];else if(m==="("&&!k&&!j)i.push(m),j=!0;else if(m===")"&&!k&&j)i.push(m),j=!1;else{if(m==='"'||m==="'"||m==="`")k?k=k===m?!1:k:k=m;i.push(m)}}if(g>0)throw{type:"Syntax",message:"Missing closing `}`",filename:a.filename};return c.map(function(a){return a.join("")})}([[]]),h=new e.Ruleset([],s(this.parsers.primary)),h.root=!0,h.toCSS=function(c){var d,f,g;return function(g,h){function n(a){return a?(b.slice(0,a).match(/\n/g)||"").length:null}var i=[];g=g||{},typeof h=="object"&&!Array.isArray(h)&&(h=Object.keys(h).map(function(a){var b=h[a];return b instanceof e.Value||(b instanceof e.Expression||(b=new e.Expression([b])),b=new e.Value([b])),new e.Rule("@"+a,b,!1,0)}),i=[new e.Ruleset(null,h)]);try{var j=c.call(this,{frames:i}).toCSS([],{compress:g.compress||!1})}catch(k){f=b.split("\n"),d=n(k.index);for(var
l=k.index,m=-1;l>=0&&b.charAt(l)!=="\n";l--)m++;throw{type:k.type,message:k.message,filename:a.filename,index:k.index,line:typeof d=="number"?d+1:null,callLine:k.call&&n(k.call)+1,callExtract:f[n(k.call)],stack:k.stack,column:m,extract:[f[d-1],f[d],f[d+1]]}}return g.compress?j.replace(/(\s)+/g,"$1"):j}}(h.eval);if(c<b.length-1){c=i,q=b.split("\n"),p=(b.slice(0,c).match(/\n/g)||"").length+1;for(var v=c,w=-1;v>=0&&b.charAt(v)!=="\n";v--)w++;u={name:"ParseError",message:"Syntax Error on line "+p,index:c,filename:a.filename,line:p,column:w,extract:[q[p-2],q[p-1],q[p]]}}this.imports.queue.length>0?n=function(){g(u,h)}:g(u,h)},parsers:{primary:function(){var a,b=[];while((a=s(this.mixin.definition)||s(this.rule)||s(this.ruleset)||s(this.mixin.call)||s(this.comment)||s(this.directive))||s(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(b.charAt(c)!==&qu
ot;/")return;if(b.charAt(c+1)==="/")return new e.Comment(s(/^\/\/.*/),!0);if(a=s(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new e.Comment(a)},entities:{quoted:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)!=='"'&&b.charAt(d)!=="'")return;f&&s("~");if(a=s(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new e.Quoted(a[0],a[1]||a[2],f)},keyword:function(){var a;if(a=s(/^[_A-Za-z-][_A-Za-z0-9-]*/))return new e.Keyword(a)},call:function(){var a,b,d=c;if(!(a=/^([\w-]+|%)\(/.exec(j[f])))return;a=a[1].toLowerCase();if(a==="url")return null;c+=a.length;if(a==="alpha")return s(this.alpha);s("("),b=s(this.entities.arguments);if(!s(")"))return;if(a)return new e.Call(a,b,d)},arguments:function(){var a=[],b;while(b=s(this.expression)){a.push(b);if(!s(","))break}return a},literal:function(){return s(this.entities.dimension)||s(th
is.entities.color)||s(this.entities.quoted)},url:function(){var a;if(b.charAt(c)!=="u"||!s(/^url\(/))return;a=s(this.entities.quoted)||s(this.entities.variable)||s(this.entities.dataURI)||s(/^[-\w%@$\/.&=:;#+?~]+/)||"";if(!s(")"))throw new Error("missing closing ) for url()");return new e.URL(a.value||a.data||a instanceof e.Variable?a:new e.Anonymous(a),o.paths)},dataURI:function(){var a;if(s(/^data:/)){a={},a.mime=s(/^[^\/]+\/[^,;)]+/)||"",a.charset=s(/^;\s*charset=[^,;)]+/)||"",a.base64=s(/^;\s*base64/)||"",a.data=s(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var a,d=c;if(b.charAt(c)==="@"&&(a=s(/^@@?[\w-]+/)))return new e.Variable(a,d)},color:function(){var a;if(b.charAt(c)==="#"&&(a=s(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new e.Color(a[1])},dimension:function(){var a,d=b.charCodeAt(c);if(d>57||d<45||d===47)return;if(a=s(/^(-?\d*\.?\d+)(px|%|em|pc|
ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new e.Dimension(a[1],a[2])},javascript:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)!=="`")return;f&&s("~");if(a=s(/^`([^`]*)`/))return new e.JavaScript(a[1],c,f)}},variable:function(){var a;if(b.charAt(c)==="@"&&(a=s(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!t(/^[@\w.%-]+\/[@\w.-]+/))return;if((a=s(this.entity))&&s("/")&&(b=s(this.entity)))return new e.Shorthand(a,b)},mixin:{call:function(){var a=[],d,f,g,h=c,i=b.charAt(c);if(i!=="."&&i!=="#")return;while(d=s(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))a.push(new e.Element(f,d,c)),f=s(">");s("(")&&(g=s(this.entities.arguments))&&s(")");if(a.length>0&&(s(";")||t("}")))return new e.mixin.Call(a,g,h)},definition:function(){var a,d=[],f
,g,h,i;if(b.charAt(c)!=="."&&b.charAt(c)!=="#"||t(/^[^{]*(;|})/))return;if(f=s(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=f[1];while(h=s(this.entities.variable)||s(this.entities.literal)||s(this.entities.keyword)){if(h instanceof e.Variable)if(s(":"))if(i=s(this.expression))d.push({name:h.name,value:i});else throw new Error("Expected value");else d.push({name:h.name});else d.push({value:h});if(!s(","))break}if(!s(")"))throw new Error("Expected )");g=s(this.block);if(g)return new e.mixin.Definition(a,d,g)}}},entity:function(){return s(this.entities.literal)||s(this.entities.variable)||s(this.entities.url)||s(this.entities.call)||s(this.entities.keyword)||s(this.entities.javascript)||s(this.comment)},end:function(){return s(";")||t("}")},alpha:function(){var a;if(!s(/^\(opacity=/i))return;if(a=s(/^\d+/)||s(this.entities.variable)){if(!s(")"))throw new Err
or("missing closing ) for alpha()");return new e.Alpha(a)}},element:function(){var a,b,d;d=s(this.combinator),a=s(/^(?:\d+\.\d+|\d+)%/)||s(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||s("*")||s(this.attribute)||s(/^\([^)@]+\)/);if(a)return new e.Element(d,a,c);if(d.value&&d.value.charAt(0)==="&")return new e.Element(d,null,c)},combinator:function(){var a,d=b.charAt(c);if(d===">"||d==="+"||d==="~"){c++;while(b.charAt(c)===" ")c++;return new e.Combinator(d)}if(d==="&"){a="&",c++,b.charAt(c)===" "&&(a="& ");while(b.charAt(c)===" ")c++;return new e.Combinator(a)}if(d===":"&&b.charAt(c+1)===":"){c+=2;while(b.charAt(c)===" ")c++;return new e.Combinator("::")}return b.charAt(c-1)===" "?new e.Combinator(" "):new e.Combinator(null)},selector:function()
{var a,d,f=[],g,h;while(d=s(this.element)){g=b.charAt(c),f.push(d);if(g==="{"||g==="}"||g===";"||g===",")break}if(f.length>0)return new e.Selector(f)},tag:function(){return s(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||s("*")},attribute:function(){var a="",b,c,d;if(!s("["))return;if(b=s(/^[a-zA-Z-]+/)||s(this.entities.quoted))(d=s(/^[|~*$^]?=/))&&(c=s(this.entities.quoted)||s(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!s("]"))return;if(a)return"["+a+"]"},block:function(){var a;if(s("{")&&(a=s(this.primary))&&s("}"))return a},ruleset:function(){var a=[],b,d,f;p();while(b=s(this.selector)){a.push(b),s(this.comment);if(!s(","))break;s(this.comment)}if(a.length>0&&(d=s(this.block)))return new e.Ruleset(a,d);i=c,q()},rule:function(){var a,d,g=b.charAt(c),k,l;p();if(g==="."||g==="#"||g==="&
amp;")return;if(a=s(this.variable)||s(this.property)){a.charAt(0)!="@"&&(l=/^([^@+\/'"*`(;{}-]*);/.exec(j[f]))?(c+=l[0].length-1,d=new e.Anonymous(l[1])):a==="font"?d=s(this.font):d=s(this.value),k=s(this.important);if(d&&s(this.end))return new e.Rule(a,d,k,h);i=c,q()}},"import":function(){var a;if(s(/^@import\s+/)&&(a=s(this.entities.quoted)||s(this.entities.url))&&s(";"))return new e.Import(a,o)},directive:function(){var a,d,f,g;if(b.charAt(c)!=="@")return;if(d=s(this["import"]))return d;if(a=s(/^@media|@page/)||s(/^@(?:-webkit-|-moz-)?keyframes/)){g=(s(/^[^{]+/)||"").trim();if(f=s(this.block))return new e.Directive(a+" "+g,f)}else if(a=s(/^@[-a-z]+/))if(a==="@font-face"){if(f=s(this.block))return new e.Directive(a,f)}else if((d=s(this.entity))&&s(";"))return new e.Directive(a,d)},font:function(){var a=[],b=[],c,d,f,g;while(g=s(this.
shorthand)||s(this.entity))b.push(g);a.push(new e.Expression(b));if(s(","))while(g=s(this.expression)){a.push(g);if(!s(","))break}return new e.Value(a)},value:function(){var a,b=[],c;while(a=s(this.expression)){b.push(a);if(!s(","))break}if(b.length>0)return new e.Value(b)},important:function(){if(b.charAt(c)==="!")return s(/^! *important/)},sub:function(){var a;if(s("(")&&(a=s(this.expression))&&s(")"))return a},multiplication:function(){var a,b,c,d;if(a=s(this.operand)){while((c=s("/")||s("*"))&&(b=s(this.operand)))d=new e.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,d,f,g;if(a=s(this.multiplication)){while((f=s(/^[-+]\s+/)||b.charAt(c-1)!=" "&&(s("+")||s("-")))&&(d=s(this.multiplication)))g=new e.Operation(f,[g||a,d]);return g||a}},operand:function(){var a,d=b.charAt(c+1);b.charAt(c)==="-"&&(d==
="@"||d==="(")&&(a=s("-"));var f=s(this.sub)||s(this.entities.dimension)||s(this.entities.color)||s(this.entities.variable)||s(this.entities.call);return a?new e.Operation("*",[new e.Dimension(-1),f]):f},expression:function(){var a,b,c=[],d;while(a=s(this.addition)||s(this.entity))c.push(a);if(c.length>0)return new e.Expression(c)},property:function(){var a;if(a=s(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}};if(d.mode==="browser"||d.mode==="rhino")d.Parser.importer=function(a,b,c,d){a.charAt(0)!=="/"&&b.length>0&&(a=b[0]+a),n({href:a,title:a,type:d.mime},c,!0)};(function(a){function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function d(a){retu
rn Math.min(1,Math.max(0,a))}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){return a=a<0?a+1:a>1?a-1:a,a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(Math.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();return e.s+=c.value/100,e.s=d(e.s),b(e)},desaturate:function(a,c){var e=a.toHSL();return e.s-=c.value/100,e.s=d(e.s),b(e)},lighten:function(a,c){var e=a.toHSL();r
eturn e.l+=c.value/100,e.l=d(e.l),b(e)},darken:function(a,c){var e=a.toHSL();return e.l-=c.value/100,e.l=d(e.l),b(e)},fadein:function(a,c){var e=a.toHSL();return e.a+=c.value/100,e.a=d(e.a),b(e)},fadeout:function(a,c){var e=a.toHSL();return e.a-=c.value/100,e.a=d(e.a),b(e)},fade:function(a,c){var e=a.toHSL();return e.a=c.value/100,e.a=d(e.a),b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;return d.h=e<0?360+e:e,b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B"
;).replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e<c.length;e++)d=d.replace(/%[sda]/i,function(a){var b=a.match(/s/i)?c[e].value:c[e].toCSS();return a.match(/[A-Z]$/)?encodeURIComponent(b):b});return d=d.replace(/%%/g,"%"),new a.Quoted('"'+d+'"',d)},round:function(b){if(b instanceof a.Dimension)return new a.Dimension(Math.round(c(b)),b.unit);if(typeof b=="number")return Math.round(b);throw{error:"RuntimeError",message:"math functions take numbers as parameters"}},argb:function(b){return new a.Anonymous(b.toARGB())}}})(c("./tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(a){return this.value.eval&&(this.value=this.value.eval(a)),this}}}(c("../tree&q
uot;)),function(a){a.Anonymous=function(a){this.value=a.value||a},a.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Call=function(a,b,c){this.name=a,this.args=b,this.index=c},a.Call.prototype={eval:function(b){var c=this.args.map(function(a){return a.eval(b)});if(!(this.name in a.functions))return new a.Anonymous(this.name+"("+c.map(function(a){return a.toCSS()}).join(", ")+")");try{return a.functions[this.name].apply(a.functions,c)}catch(d){throw{message:"error evaluating function `"+this.name+"`",index:this.index}}},toCSS:function(a){return this.eval(a).toCSS()}}}(c("../tree")),function(a){a.Color=function(a,b){Array.isArray(a)?this.rgb=a:a.length==6?this.rgb=a.match(/.{2}/g).map(function(a){return parseInt(a,16)}):this.rgb=a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha=typeof b=="number"?b:1},a.Color.protot
ype={eval:function(){return this},toCSS:function(){return this.alpha<1?"rgba("+this.rgb.map(function(a){return Math.round(a)}).concat(this.alpha).join(", ")+")":"#"+this.rgb.map(function(a){return a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);switch(e){case a:g=(b-c)/j+(b<c?6:0);break;case b:g=(c-a)/j+2;break;case c:g=(a-b)/j+4}g/=6}return{h:g*360,s:h,l:i,a:d}},toARGB:function(){var a=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+a.map(function(a){return a=Math.round(a),a=(a>255?255:a<0?0:a)
.toString(16),a.length===1?"0"+a:a}).join("")}}}(c("../tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)}}}(c("../tree")),function(a){a.Directive=function(b,c){this.name=b,Array.isArray(c)?this.ruleset=new a.Ruleset([],c):this.value=c},a.Directive.prototype={toCSS:function(a,b){return this.ruleset?(this.ruleset.root=!0,this.name+(b.compress?"{":" {\n ")+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n "
;)+(b.compress?"}":"\n}\n")):this.name+" "+this.value.toCSS()+";\n"},eval:function(a){return a.frames.unshift(this),this.ruleset=this.ruleset&&this.ruleset.eval(a),a.frames.shift(),this},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(c("../tree")),function(a){a.Element=function(b,c,d){this.combinator=b instanceof a.Combinator?b:new a.Combinator(b),this.value=c?c.trim():"",this.index=d},a.Element.prototype.toCSS=function(a){return this.combinator.toCSS(a||{})+this.value},a.Combinator=function(a){a===" "?this.value=" ":a==="& "?this.value="& ":this.value=a?a.trim():""},a.Combinator.prototype.toCSS=function(a){return{"":""," ":" ","
;&":"","& ":" ",":":" :","::":"::","+":a.compress?"+":" + ","~":a.compress?"~":" ~ ",">":a.compress?">":" > "}[this.value]}}(c("../tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(" ")}}}(c("../tree")),function(a){a.Import=function(b,c){var d=this;this._path=b,b instanceof a.Quoted?this.path=/\.(le?|c)ss(\?.*)?$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value||b.value,this.css=/css(\?.*)?$/.test(this.path),this.css||c.push(this.path,function(a){if(!a)throw new Error("Error parsi
ng "+d.path);d.root=a})},a.Import.prototype={toCSS:function(){return this.css?"@import "+this._path.toCSS()+";\n":""},eval:function(b){var c;if(this.css)return this;c=new a.Ruleset(null,this.root.rules.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));return c.rules}}}(c("../tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify((new a.Variable("@"+e,d.index)).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: `"+f+"`",index:this.index}}for(var h in b.frames[0].variables())e[h.slice(1)]={value:b.frames[0].variables()[h].value,toJS:function(){return this.value.eval(b).
toCSS()}};try{c=f.call(e)}catch(g){throw{message:"JavaScript evaluation error: '"+g.name+": "+g.message+"'",index:this.index}}return typeof c=="string"?new a.Quoted('"'+c+'"',c,this.escaped,this.index):Array.isArray(c)?new a.Anonymous(c.join(", ")):new a.Anonymous(c)}}}(c("../tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value}}}(c("../tree")),function(a){a.mixin={},a.mixin.Call=function(b,c,d){this.selector=new a.Selector(b),this.arguments=c,this.index=d},a.mixin.Call.prototype={eval:function(a){var b,c,d=[],e=!1;for(var f=0;f<a.frames.length;f++)if((b=a.frames[f].find(this.selector)).length>0){c=this.arguments&&this.arguments.map(function(b){return b.eval(a)});for(var g=0;g<b.length;g++)if(b[g].match(c,a))try{Array.prototype.push.apply(d,b[g].eval(a,this.arguments).rules),e=!0}catch(h){throw{messag
e:h.message,index:h.index,stack:h.stack,call:this.index}}if(e)return d;throw{message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(a){return a.toCSS()}).join(", ")+")`",index:this.index}}throw{message:this.selector.toCSS().trim()+" is undefined",index:this.index}}},a.mixin.Definition=function(b,c,d){this.name=b,this.selectors=[new a.Selector([new a.Element(null,b)])],this.params=c,this.arity=c.length,this.rules=d,this._lookups={},this.required=c.reduce(function(a,b){return!b.name||b.name&&!b.value?a+1:a},0),this.parent=a.Ruleset.prototype,this.frames=[]},a.mixin.Definition.prototype={toCSS:function(){return""},variable:function(a){return this.parent.variable.call(this,a)},variables:function(){return this.parent.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},eval:f
unction(b,c){var d=new a.Ruleset(null,[]),e,f=[];for(var g=0,h;g<this.params.length;g++)if(this.params[g].name)if(h=c&&c[g]||this.params[g].value)d.rules.unshift(new a.Rule(this.params[g].name,h.eval(b)));else throw{message:"wrong number of arguments for "+this.name+" ("+c.length+" for "+this.arity+")"};for(var g=0;g<Math.max(this.params.length,c&&c.length);g++)f.push(c[g]||this.params[g].value);return d.rules.unshift(new a.Rule("@arguments",(new a.Expression(f)).eval(b))),(new a.Ruleset(null,this.rules.slice(0))).eval({frames:[this,d].concat(this.frames,b.frames)})},match:function(a,b){var c=a&&a.length||0,d;if(c<this.required)return!1;if(this.required>0&&c>this.params.length)return!1;d=Math.min(c,this.arity);for(var e=0;e<d;e++)if(!this.params[e].name&&a[e].eval(b).toCSS()!=this.params[e].value.eval(b).toCSS())return!1;return!0}}}(c("../tree")),function(a){a.Operat
ion=function(a,b){this.op=a.trim(),this.operands=b},a.Operation.prototype.eval=function(b){var c=this.operands[0].eval(b),d=this.operands[1].eval(b),e;if(c instanceof a.Dimension&&d instanceof a.Color)if(this.op==="*"||this.op==="+")e=d,d=c,c=e;else throw{name:"OperationError",message:"Can't substract or divide a color from a number"};return c.operate(this.op,d)},a.operate=function(a,b,c){switch(a){case"+":return b+c;case"-":return b-c;case"*":return b*c;case"/":return b/c}}}(c("../tree")),function(a){a.Quoted=function(a,b,c,d){this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d},a.Quoted.prototype={toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(b){var c=this,d=this.value.replace(/`([^`]+)`/g,function(d,e){return(new a.JavaScript(e,c.index,!0)).eval(b).value}).replace(/@\{([\w-]+)\}/g,function(d,e){var f=(new a.V
ariable("@"+e,c.index)).eval(b);return f.value||f.toCSS()});return new a.Quoted(this.quote+d+this.quote,d,this.escaped,this.index)}}}(c("../tree")),function(a){a.Rule=function(b,c,d,e){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.index=e,b.charAt(0)==="@"?this.variable=!0:this.variable=!1},a.Rule.prototype.toCSS=function(a){return this.variable?"":this.name+(a.compress?":":": ")+this.value.toCSS(a)+this.important+";"},a.Rule.prototype.eval=function(b){return new a.Rule(this.name,this.value.eval(b),this.important,this.index)},a.Shorthand=function(a,b){this.a=a,this.b=b},a.Shorthand.prototype={toCSS:function(a){return this.a.toCSS(a)+"/"+this.b.toCSS(a)},eval:function(){return this}}}(c("../tree")),function(a){a.Ruleset=function(a,b){this.selectors=a,this.rules=b,this._lookups={}},a.Ruleset.prototype={eval:function(b){var
c=new a.Ruleset(this.selectors,this.rules.slice(0));c.root=this.root,b.frames.unshift(c);if(c.root)for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Definition&&(c.rules[d].frames=b.frames.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Call&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0,e;d<c.rules.length;d++)e=c.rules[d],e instanceof a.mixin.Definition||(c.rules[d]=e.eval?e.eval(b):e);return b.frames.shift(),c},match:function(a){return!a||a.length===0},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(b,c){return c instanceof a.Rule&&c.variable===!0&&(b[c.name]=c),b},{})},variable:function(a){return this.variables()[a]},rulesets:function(){return this._rulesets?this._rules
ets:this._rulesets=this.rules.filter(function(b){return b instanceof a.Ruleset||b instanceof a.mixin.Definition})},find:function(b,c){c=c||this;var d=[],e,f,g=b.toCSS();return g in this._lookups?this._lookups[g]:(this.rulesets().forEach(function(e){if(e!==c)for(var g=0;g<e.selectors.length;g++)if(f=b.match(e.selectors[g])){b.elements.length>e.selectors[g].elements.length?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}}),this._lookups[g]=d)},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;this.root||(b.length===0?g=this.selectors.map(function(a){return[a]}):this.joinSelectors(g,b,this.selectors));for(var j=0;j<this.rules.length;j++)i=this.rules[j],i.rules||i instanceof a.Directive?f.push(i.toCSS(g,c)):i instanceof a.Comment?i.silent||(this.root?f.push(i.toCSS(c)):e.push(i.toCSS(c))):i.toCSS&&!i.variable?e.push(i.toCSS(c)):i.value&&!i.variable&&e.push(i.value.toString());return f=f.join(""),this.ro
ot?d.push(e.join(c.compress?"":"\n")):e.length>0&&(h=g.map(function(a){return a.map(function(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":g.length>3?",\n":", "),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f),d.join("")+(c.compress?"\n":"")},joinSelectors:function(a,b,c){for(var d=0;d<c.length;d++)this.joinSelector(a,b,c[d])},joinSelector:function(b,c,d){var e=[],f=[],g=[],h=[],i=!1,j;for(var k=0;k<d.elements.length;k++)j=d.elements[k],j.combinator.value.charAt(0)==="&"&&(i=!0),i?h.push(j):g.push(j);i||(h=g,g=[]),g.length>0&&e.push(new a.Selector(g)),h.length>0&&f.push(new a.Selector(h));for(var l=0;l<c.length;l++)b.push(e.concat(c[l]).concat(f))}}}(c("../tree")),function(a){a.Selector=functi
on(a){this.elements=a,this.elements[0].combinator.value===""&&(this.elements[0].combinator.value=" ")},a.Selector.prototype.match=function(a){var b=this.elements.length,c=a.elements.length,d=Math.min(b,c);if(b<c)return!1;for(var e=0;e<d;e++)if(this.elements[e].value!==a.elements[e].value)return!1
+;return!0},a.Selector.prototype.toCSS=function(a){return this._css?this._css:this._css=this.elements.map(function(b){return typeof b=="string"?" "+b.trim():b.toCSS(a)}).join("")}}(c("../tree")),function(a){a.URL=function(a,b){a.data?this.attrs=a:(d.mode==="browser"&&!/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(a.value)&&b.length>0&&(a.value=b[0]+(a.value.charAt(0)==="/"?a.value.slice(1):a.value)),this.value=a,this.paths=b)},a.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(b){return this.attrs?this:new a.URL(this.value.eval(b),this.paths)}}}(c("../tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.ma
p(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("../tree")),function(a){a.Variable=function(a,b){this.name=a,this.index=b},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{message:"variable "+e+" is undefined",index:this.index}}}}(c("../tree")),c("./tree").find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null},c("./tree").jsify=function(a){return Array.isArray(a.value)&&a.value.length>1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)};var f=location.protocol==="file:"||location.protocol==="chrome:&q
uot;||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||f?"development":"production"),d.async=!1,d.poll=d.poll||(f?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&m(function(a,b,c){a&&p(a.toCSS(),b,c.lastModified)})},d.poll)):d.optimization=3;var g;try{g=typeof a.localStorage=="undefined"?null:a.localStorage}catch(h){g=null}var i=document.getElementsByTagName("link"),j=/^text\/(x-)?less$/;d.sheets=[];for(var k=0;k<i.length;k++)(i[k].rel==="stylesheet/less"||i[k].rel.match(/stylesheet/)&&i[k].type.match(j))
&&d.sheets.push(i[k]);d.refresh=function(a){var b,c;b=c=new Date,m(function(a,d,e){e.local?t("loading "+d.href+" from cache."):(t("parsed "+d.href+" successfully."),p(a.toCSS(),d,e.lastModified)),t("css for "+d.href+" generated in "+(new Date-c)+"ms"),e.remaining===0&&t("css generated in "+(new Date-b)+"ms"),c=new Date},a),l()},d.refreshStyles=l,d.refresh(d.env==="development")})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless116js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.6.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.6.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.6.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3004 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.6
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+ // Rhino
+ // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+ less = {};
+ tree = less.tree = {};
+ less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+ // Node.js
+ less = exports,
+ tree = require('./tree');
+ less.mode = 'node';
+} else {
+ // Browser
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+ less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ mime: env && env.mime, // MIME type of .less files
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (root) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+
+ callback(root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ chunks = [];
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam,
+ inString;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = i;
+
+ if (!inString && !inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ if (c === '{' && !inString && !inParam) { level ++;
+ chunk.push(c);
+ } else if (c === '}' && !inString && !inParam) { level --;
+ chunk.push(c);
+ chunks[++j] = chunk = [];
+ } else if (c === '(' && !inString && !inParam) {
+ chunk.push(c);
+ inParam = true;
+ } else if (c === ')' && !inString && inParam) {
+ chunk.push(c);
+ inParam = false;
+ } else {
+ if (c === '"' || c === "'" || c === '`') {
+ if (! inString) {
+ inString = c;
+ } else {
+ inString = inString === c ? false : inString;
+ }
+ }
+ chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ throw {
+ type: 'Syntax',
+ message: "Missing closing `}`",
+ filename: env.filename
+ };
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [];
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ lines = input.split('\n');
+ line = getLine(e.index);
+
+ for (var n = e.index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ throw {
+ type: e.type,
+ message: e.message,
+ filename: env.filename,
+ index: e.index,
+ line: typeof(line) === 'number' ? line + 1 : null,
+ callLine: e.call && (getLine(e.call) + 1),
+ callExtract: lines[getLine(e.call)],
+ stack: e.stack,
+ column: column,
+ extract: [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ]
+ };
+ }
+ if (options.yuicompress && less.mode === 'node') {
+ return require('./cssmin').compressor.cssmin(css);
+ } else if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+
+ function getLine(index) {
+ return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ name: "ParseError",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+
+ if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+ if (tree.colors.hasOwnProperty(k)) {
+ // detect named color
+ return new(tree.Color)(tree.colors[k].slice(1));
+ } else {
+ return new(tree.Keyword)(k)
+ }
+ }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args, index = i;
+
+ if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args, index) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.entities.assignment) || $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ // Assignments are argument entities for calls.
+ // They are present in ie filter properties as shown below.
+ //
+ // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+ //
+
+ assignment: function () {
+ var key, value;
+ if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+ return new(tree.Assignment)(key, value);
+ }
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+ if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e, i));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value;
+
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ while (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ if (value = $(this.expression)) {
+ params.push({ name: param.name, value: value });
+ } else {
+ throw new(Error)("Expected value");
+ }
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ if (! $(',')) { break }
+ }
+ if (! $(')')) throw new(Error)("Expected )");
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset);
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^\(opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c;
+
+ c = $(this.combinator);
+ e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+ $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+ if (e) { return new(tree.Element)(c, e, i) }
+
+ if (c.value && c.value.charAt(0) === '&') {
+ return new(tree.Element)(c, null, i);
+ }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === '&') {
+ match = '&';
+ i++;
+ if(input.charAt(i) === ' ') {
+ match = '& ';
+ }
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(match);
+ } else if (c === ':' && input.charAt(i + 1) === ':') {
+ i += 2;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)('::');
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url)) &&
+ $(';')) {
+ return new(tree.Import)(path, imports);
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import'])) {
+ return value;
+ } else if (name = $(/^@media|@page/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/) || $('keyframes')) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (path.charAt(0) !== '/' && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fade: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a = amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ return this._math('round', n);
+ },
+ ceil: function (n) {
+ return this._math('ceil', n);
+ },
+ floor: function (n) {
+ return this._math('floor', n);
+ },
+ _math: function (fn, n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math[fn](n);
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "math functions take numbers as parameters"
+ };
+ }
+ },
+ argb: function (color) {
+ return new(tree.Anonymous)(color.toARGB());
+
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+ tree.colors = {
+ 'aliceblue':'#f0f8ff',
+ 'antiquewhite':'#faebd7',
+ 'aqua':'#00ffff',
+ 'aquamarine':'#7fffd4',
+ 'azure':'#f0ffff',
+ 'beige':'#f5f5dc',
+ 'bisque':'#ffe4c4',
+ 'black':'#000000',
+ 'blanchedalmond':'#ffebcd',
+ 'blue':'#0000ff',
+ 'blueviolet':'#8a2be2',
+ 'brown':'#a52a2a',
+ 'burlywood':'#deb887',
+ 'cadetblue':'#5f9ea0',
+ 'chartreuse':'#7fff00',
+ 'chocolate':'#d2691e',
+ 'coral':'#ff7f50',
+ 'cornflowerblue':'#6495ed',
+ 'cornsilk':'#fff8dc',
+ 'crimson':'#dc143c',
+ 'cyan':'#00ffff',
+ 'darkblue':'#00008b',
+ 'darkcyan':'#008b8b',
+ 'darkgoldenrod':'#b8860b',
+ 'darkgray':'#a9a9a9',
+ 'darkgrey':'#a9a9a9',
+ 'darkgreen':'#006400',
+ 'darkkhaki':'#bdb76b',
+ 'darkmagenta':'#8b008b',
+ 'darkolivegreen':'#556b2f',
+ 'darkorange':'#ff8c00',
+ 'darkorchid':'#9932cc',
+ 'darkred':'#8b0000',
+ 'darksalmon':'#e9967a',
+ 'darkseagreen':'#8fbc8f',
+ 'darkslateblue':'#483d8b',
+ 'darkslategray':'#2f4f4f',
+ 'darkslategrey':'#2f4f4f',
+ 'darkturquoise':'#00ced1',
+ 'darkviolet':'#9400d3',
+ 'deeppink':'#ff1493',
+ 'deepskyblue':'#00bfff',
+ 'dimgray':'#696969',
+ 'dimgrey':'#696969',
+ 'dodgerblue':'#1e90ff',
+ 'firebrick':'#b22222',
+ 'floralwhite':'#fffaf0',
+ 'forestgreen':'#228b22',
+ 'fuchsia':'#ff00ff',
+ 'gainsboro':'#dcdcdc',
+ 'ghostwhite':'#f8f8ff',
+ 'gold':'#ffd700',
+ 'goldenrod':'#daa520',
+ 'gray':'#808080',
+ 'grey':'#808080',
+ 'green':'#008000',
+ 'greenyellow':'#adff2f',
+ 'honeydew':'#f0fff0',
+ 'hotpink':'#ff69b4',
+ 'indianred':'#cd5c5c',
+ 'indigo':'#4b0082',
+ 'ivory':'#fffff0',
+ 'khaki':'#f0e68c',
+ 'lavender':'#e6e6fa',
+ 'lavenderblush':'#fff0f5',
+ 'lawngreen':'#7cfc00',
+ 'lemonchiffon':'#fffacd',
+ 'lightblue':'#add8e6',
+ 'lightcoral':'#f08080',
+ 'lightcyan':'#e0ffff',
+ 'lightgoldenrodyellow':'#fafad2',
+ 'lightgray':'#d3d3d3',
+ 'lightgrey':'#d3d3d3',
+ 'lightgreen':'#90ee90',
+ 'lightpink':'#ffb6c1',
+ 'lightsalmon':'#ffa07a',
+ 'lightseagreen':'#20b2aa',
+ 'lightskyblue':'#87cefa',
+ 'lightslategray':'#778899',
+ 'lightslategrey':'#778899',
+ 'lightsteelblue':'#b0c4de',
+ 'lightyellow':'#ffffe0',
+ 'lime':'#00ff00',
+ 'limegreen':'#32cd32',
+ 'linen':'#faf0e6',
+ 'magenta':'#ff00ff',
+ 'maroon':'#800000',
+ 'mediumaquamarine':'#66cdaa',
+ 'mediumblue':'#0000cd',
+ 'mediumorchid':'#ba55d3',
+ 'mediumpurple':'#9370d8',
+ 'mediumseagreen':'#3cb371',
+ 'mediumslateblue':'#7b68ee',
+ 'mediumspringgreen':'#00fa9a',
+ 'mediumturquoise':'#48d1cc',
+ 'mediumvioletred':'#c71585',
+ 'midnightblue':'#191970',
+ 'mintcream':'#f5fffa',
+ 'mistyrose':'#ffe4e1',
+ 'moccasin':'#ffe4b5',
+ 'navajowhite':'#ffdead',
+ 'navy':'#000080',
+ 'oldlace':'#fdf5e6',
+ 'olive':'#808000',
+ 'olivedrab':'#6b8e23',
+ 'orange':'#ffa500',
+ 'orangered':'#ff4500',
+ 'orchid':'#da70d6',
+ 'palegoldenrod':'#eee8aa',
+ 'palegreen':'#98fb98',
+ 'paleturquoise':'#afeeee',
+ 'palevioletred':'#d87093',
+ 'papayawhip':'#ffefd5',
+ 'peachpuff':'#ffdab9',
+ 'peru':'#cd853f',
+ 'pink':'#ffc0cb',
+ 'plum':'#dda0dd',
+ 'powderblue':'#b0e0e6',
+ 'purple':'#800080',
+ 'red':'#ff0000',
+ 'rosybrown':'#bc8f8f',
+ 'royalblue':'#4169e1',
+ 'saddlebrown':'#8b4513',
+ 'salmon':'#fa8072',
+ 'sandybrown':'#f4a460',
+ 'seagreen':'#2e8b57',
+ 'seashell':'#fff5ee',
+ 'sienna':'#a0522d',
+ 'silver':'#c0c0c0',
+ 'skyblue':'#87ceeb',
+ 'slateblue':'#6a5acd',
+ 'slategray':'#708090',
+ 'slategrey':'#708090',
+ 'snow':'#fffafa',
+ 'springgreen':'#00ff7f',
+ 'steelblue':'#4682b4',
+ 'tan':'#d2b48c',
+ 'teal':'#008080',
+ 'thistle':'#d8bfd8',
+ 'tomato':'#ff6347',
+ 'turquoise':'#40e0d0',
+ 'violet':'#ee82ee',
+ 'wheat':'#f5deb3',
+ 'white':'#ffffff',
+ 'whitesmoke':'#f5f5f5',
+ 'yellow':'#ffff00',
+ 'yellowgreen':'#9acd32'
+ };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+ this.key = key;
+ this.value = val;
+};
+tree.Assignment.prototype = {
+ toCSS: function () {
+ return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+ this.name = name;
+ this.args = args;
+ this.index = index;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ try {
+ return tree.functions[this.name].apply(tree.functions, args);
+ } catch (e) {
+ throw { message: "error evaluating function `" + this.name + "`",
+ index: this.index };
+ }
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ },
+ toARGB: function () {
+ var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+ return '#' + argb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+ this.name = name;
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+ this.value = value ? value.trim() : "";
+ this.index = index;
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else if (value === '& ') {
+ this.value = '& ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ '& ' : ' ',
+ ':' : ' :',
+ '::': '::',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(' ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+ var that = this;
+
+ this._path = path;
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css(\?.*)?$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (root) {
+ if (! root) {
+ throw new(Error)("Error parsing " + that.path);
+ }
+ that.root = root;
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function () {
+ if (this.css) {
+ return "@import " + this._path.toCSS() + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset;
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return ruleset.rules;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index };
+ }
+ }
+ }
+ throw { message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ eval: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+ for (var i = 0, val; i < this.params.length; i++) {
+ if (this.params[i].name) {
+ if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+ } else {
+ throw { message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len;
+
+ if (argsLength < this.required) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return v.value || v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + ";";
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+ ruleset.root = this.root;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > rule.selectors[j].elements.length) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ this.joinSelectors( paths, context, this.selectors );
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ },
+
+ joinSelectors: function (paths, context, selectors) {
+ for (var s = 0; s < selectors.length; s++) {
+ this.joinSelector(paths, context, selectors[s]);
+ }
+ },
+
+ joinSelector: function (paths, context, selector) {
+ var before = [], after = [], beforeElements = [],
+ afterElements = [], hasParentSelector = false, el;
+
+ for (var i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ if (el.combinator.value.charAt(0) === '&') {
+ hasParentSelector = true;
+ }
+ if (hasParentSelector) afterElements.push(el);
+ else beforeElements.push(el);
+ }
+
+ if (! hasParentSelector) {
+ afterElements = beforeElements;
+ beforeElements = [];
+ }
+
+ if (beforeElements.length > 0) {
+ before.push(new(tree.Selector)(beforeElements));
+ }
+
+ if (afterElements.length > 0) {
+ after.push(new(tree.Selector)(afterElements));
+ }
+
+ for (var c = 0; c < context.length; c++) {
+ paths.push(before.concat(context[c]).concat(after));
+ }
+ }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ var len = this.elements.length,
+ olen = other.elements.length,
+ max = Math.min(len, olen);
+
+ if (len < olen) {
+ return false;
+ } else {
+ for (var i = 0; i < max; i++) {
+ if (this.elements[i].value !== other.elements[i].value) {
+ return false;
+ }
+ }
+ }
+ return true;
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (typeof(window) !== 'undefined' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { message: "variable " + name + " is undefined",
+ index: this.index };
+ }
+ }
+};
+
+})(require('../tree'));
+require('./tree').find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+require('./tree').jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:' ||
+ location.protocol === 'chrome:' ||
+ location.protocol === 'chrome-extension:' ||
+ location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (root, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (root, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+ var css = tree.toCSS();
+ var style = styles[i];
+ try {
+ style.innerHTML = css;
+ } catch (_) {
+ style.styleSheets.cssText = css;
+ }
+ style.type = 'text/css';
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^(https?|file):/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ css.media = sheet.media || 'screen';
+ css.id = id;
+ document.getElementsByTagName('head')[0].appendChild(css);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? false : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol) {
+ if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+
+ var template = ['<ul>',
+ '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+ '<li><label>[0]</label><pre>{current}</pre></li>',
+ '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+ '</ul>'].join('\n');
+
+ var elem = document.createElement('div'), timer, content;
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p><a href="' + href + '">' + href + "</a> ";
+
+ if (e.extract) {
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ template.replace(/\[(-?\d)\]/g, function (_, i) {
+ return (parseInt(e.line) + parseInt(i)) || '';
+ }).replace(/\{(\d)\}/g, function (_, i) {
+ return e.extract[parseInt(i)] || '';
+ }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+ e.extract[1].slice(e.column) + '</span>');
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #ee4444;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.ctx {',
+ 'color: #dd4444;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless116minjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.6.min.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.6.min.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.1.6.min.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+//
+// LESS - Leaner CSS v1.1.6
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function c(b){return a.less[b.split("/")[1]]}function l(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(j)&&(new d.Parser).parse(a[b].innerHTML||"",function(c,d){var e=d.toCSS(),f=a[b];try{f.innerHTML=e}catch(g){f.styleSheets.cssText=e}f.type="text/css"})}function m(a,b){for(var c=0;c<d.sheets.length;c++)n(d.sheets[c],a,b,d.sheets.length-(c+1))}function n(b,c,e,f){var h=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/,""),j=g&&g.getItem(i),k=g&&g.getItem(i+":timestamp"),l={css:j,timestamp:k};/^(https?|file):/.test(i)||(i.charAt(0)=="/"?i=a.location.protocol+"//"+a.location.host+i:i=h.slice(0,h.lastIndexOf("/")+1)+i),q(b.href,b.type,function(a,g){if(!e&&l&&g&&(new Date(g)).valueOf()===(new Date(l.timestamp)).valueOf())p(l.css,b),c(null,b,{local:!0,remaining:f});e
lse try{(new d.Parser({optimization:d.optimization,paths:[i.replace(/[\w\.-]+$/,"")],mime:b.type})).parse(a,function(a,d){if(a)return u(a,i);try{c(d,b,{local:!1,lastModified:g,remaining:f}),s(document.getElementById("less-error-message:"+o(i)))}catch(a){u(a,i)}})}catch(h){u(h,i)}},function(a,b){throw new Error("Couldn't load "+b+" ("+a+")")})}function o(a){return a.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\?.*$/,"").replace(/\.[^\.\/]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function p(a,b,c){var d,e=b.href?b.href.replace(/\?.*$/,""):"",f="less:"+(b.title||o(e));(d=document.getElementById(f))===null&&(d=document.createElement("style"),d.type="text/css",d.media=b.media||"screen",d.id=f,document.getElementsByTagName("head")[0].appendChild(d));if(d.styleSheet)try{d.style
Sheet.cssText=a}catch(h){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(a){d.childNodes.length>0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&g&&(t("saving "+e+" to cache."),g.setItem(e,a),g.setItem(e+":timestamp",c))}function q(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var g=r(),h=f?!1:d.async;typeof g.overrideMimeType=="function"&&g.overrideMimeType("text/css"),g.open("GET",a,h),g.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),g.send(null),f?g.status===0||g.status>=200&&g.status<300?c(g.responseText):e(g.status,a):h?g.onreadystatechange=function(){g.readyState==4&&i(g,c,e
)}:i(g,c,e)}function r(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){return t("browser doesn't support AJAX."),null}}function s(a){return a&&a.parentNode.removeChild(a)}function t(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: "+a)}function u(a,b){var c="less-error-message:"+o(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less
file")+"</h3>"+'<p><a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+":</p>"+e.replace(/\[(-?\d)\]/g,function(b,c){return parseInt(a.line)+parseInt(c)||""}).replace(/\{(\d)\}/g,function(b,c){return a.extract[parseInt(c)]||""}).replace(/\{current\}/,a.extract[1].slice(0,a.column)+'<span class="error">'+a.extract[1].slice(a.column)+"</span>")),f.innerHTML=h,p([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #ee4444;","padding:
4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.ctx {","color: #dd4444;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.e
nv=="development"&&(g=setInterval(function(){document.body&&(document.getElementById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d<c;d++)d in this&&a.call(b,this[d],d,this)}),Array.prototype.map||(Array.prototype.map=function(a){var b=this.length>>>0,c=new Array(b),d=arguments[1];for(var e=0;e<b;e++)e in this&&(c[e]=a.call(d,this[e],e,this));return c}),Array.prototype.filter||(Array.prototype.filter=function(a){var b=[],c=arguments[1];for(var d=0;d<this.length;d++)a.call(c,this[d])&&b.push(this[d]);return b}),Array.prototype.reduce||(Array.prototype.reduce=function(a){var b=this.length&
gt;>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.length>=2)var d=arguments[1];else do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0);for(;c<b;c++)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){var b=this.length,c=arguments[1]||0;if(!b)return-1;if(c>=b)return-1;c<0&&(c+=b);for(;c<b;c++){if(!Object.prototype.hasOwnProperty.call(this,c))continue;if(a===this[c])return c}return-1}),Object.keys||(Object.keys=function(a){var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}),String.prototype.trim||(String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")});var d,e;typeof environment=="object"&&{}.toString.call(environment)==="[object Environment]"?(d={},e=d.tree={},d.mode="rhino"):typeof
a=="undefined"?(d=exports,e=c("./tree"),d.mode="node"):(typeof a.less=="undefined"&&(a.less={}),d=a.less,e=a.less.tree={},d.mode="browser"),d.Parser=function(a){function q(){h=k[g],i=f,l=f}function r(){k[g]=h,f=i,l=f}function s(){f>l&&(k[g]=k[g].slice(f-l),l=f)}function t(a){var c,d,e,h,i,j,n,o;if(a instanceof Function)return a.call(m.parsers);if(typeof a=="string")c=b.charAt(f)===a?a:null,e=1,s();else{s();if(c=a.exec(k[g]))e=c[0].length;else return null}if(c){o=f+=e,j=f+k[g].length-e;while(f<j){h=b.charCodeAt(f);if(h!==32&&h!==10&&h!==9)break;f++}return k[g]=k[g].slice(e+(f-o)),l=f,k[g].length===0&&g<k.length-1&&g++,typeof c=="string"?c:c.length===1?c[0]:c}}function u(a){return typeof a=="string"?b.charAt(f)===a:a.test(k[g])?!0:!1}var b,f,g,h,i,j,k,l,m,n=this,o=function(){},p=this.imports={paths:a&&a.paths||[],queue:[],files:{},mime:a&
&a.mime,push:function(b,c){var e=this;this.queue.push(b),d.Parser.importer(b,this.paths,function(a){e.queue.splice(e.queue.indexOf(b),1),e.files[b]=a,c(a),e.queue.length===0&&o()},a)}};return this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.filename=this.env.filename||null,m={imports:p,parse:function(h,i){var m,n,p,q,r,s,u=[],v,w=null;f=g=l=j=0,k=[],b=h.replace(/\r\n/g,"\n"),k=function(c){var d=0,e=/[^"'`\{\}\/\(\)]+/g,f=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,g=0,h,i=c[0],j,k;for(var l=0,m,n;l<b.length;l++){e.lastIndex=l,(h=e.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0])),m=b.charAt(l),f.lastIndex=l,!k&&!j&&m==="/"&&(n=b.charAt(l+1),(n==="/"||n==="*")&&(h=f.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0]),m=b.charAt(l)));if(m==="{"&&!k&&!j)g++,i.push(m);else if(m==="}
"&&!k&&!j)g--,i.push(m),c[++d]=i=[];else if(m==="("&&!k&&!j)i.push(m),j=!0;else if(m===")"&&!k&&j)i.push(m),j=!1;else{if(m==='"'||m==="'"||m==="`")k?k=k===m?!1:k:k=m;i.push(m)}}if(g>0)throw{type:"Syntax",message:"Missing closing `}`",filename:a.filename};return c.map(function(a){return a.join("")})}([[]]),m=new e.Ruleset([],t(this.parsers.primary)),m.root=!0,m.toCSS=function(f){var g,h,i;return function(i,j){function p(a){return a?(b.slice(0,a).match(/\n/g)||"").length:null}var k=[];i=i||{},typeof j=="object"&&!Array.isArray(j)&&(j=Object.keys(j).map(function(a){var b=j[a];return b instanceof e.Value||(b instanceof e.Expression||(b=new e.Expression([b])),b=new e.Value([b])),new e.Rule("@"+a,b,!1,0)}),k=[new e.Ruleset(null,j)]);try{var l=f.call(this,{frames:k}).toCSS([],{compress:i.compress||!1})}catch(m){h=b.
split("\n"),g=p(m.index);for(var n=m.index,o=-1;n>=0&&b.charAt(n)!=="\n";n--)o++;throw{type:m.type,message:m.message,filename:a.filename,index:m.index,line:typeof g=="number"?g+1:null,callLine:m.call&&p(m.call)+1,callExtract:h[p(m.call)],stack:m.stack,column:o,extract:[h[g-1],h[g],h[g+1]]}}return i.yuicompress&&d.mode==="node"?c("./cssmin").compressor.cssmin(l):i.compress?l.replace(/(\s)+/g,"$1"):l}}(m.eval);if(f<b.length-1){f=j,s=b.split("\n"),r=(b.slice(0,f).match(/\n/g)||"").length+1;for(var x=f,y=-1;x>=0&&b.charAt(x)!=="\n";x--)y++;w={name:"ParseError",message:"Syntax Error on line "+r,index:f,filename:a.filename,line:r,column:y,extract:[s[r-2],s[r-1],s[r]]}}this.imports.queue.length>0?o=function(){i(w,m)}:i(w,m)},parsers:{primary:function(){var a,b=[];while((a=t(this.mixin.definition)||t(this.rule)||t(this.ruleset)||t(this.mix
in.call)||t(this.comment)||t(this.directive))||t(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(b.charAt(f)!=="/")return;if(b.charAt(f+1)==="/")return new e.Comment(t(/^\/\/.*/),!0);if(a=t(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new e.Comment(a)},entities:{quoted:function(){var a,c=f,d;b.charAt(c)==="~"&&(c++,d=!0);if(b.charAt(c)!=='"'&&b.charAt(c)!=="'")return;d&&t("~");if(a=t(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new e.Quoted(a[0],a[1]||a[2],d)},keyword:function(){var a;if(a=t(/^[_A-Za-z-][_A-Za-z0-9-]*/))return e.colors.hasOwnProperty(a)?new e.Color(e.colors[a].slice(1)):new e.Keyword(a)},call:function(){var a,b,c=f;if(!(a=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(k[g])))return;a=a[1].toLowerCase();if(a==="url")return null;f+=a.length;if(a==="alpha")return t(this.alpha);t("("),b=t(this.entities.arguments);if(!t("
;)"))return;if(a)return new e.Call(a,b,c)},arguments:function(){var a=[],b;while(b=t(this.entities.assignment)||t(this.expression)){a.push(b);if(!t(","))break}return a},literal:function(){return t(this.entities.dimension)||t(this.entities.color)||t(this.entities.quoted)},assignment:function(){var a,b;if((a=t(/^\w+(?=\s?=)/i))&&t("=")&&(b=t(this.entity)))return new e.Assignment(a,b)},url:function(){var a;if(b.charAt(f)!=="u"||!t(/^url\(/))return;a=t(this.entities.quoted)||t(this.entities.variable)||t(this.entities.dataURI)||t(/^[-\w%@$\/.&=:;#+?~]+/)||"";if(!t(")"))throw new Error("missing closing ) for url()");return new e.URL(a.value||a.data||a instanceof e.Variable?a:new e.Anonymous(a),p.paths)},dataURI:function(){var a;if(t(/^data:/)){a={},a.mime=t(/^[^\/]+\/[^,;)]+/)||"",a.charset=t(/^;\s*charset=[^,;)]+/)||"",a.base64=t(/^;\s*base64/)||"",a.data=t(/^,\s*[^)]+/);if(
a.data)return a}},variable:function(){var a,c=f;if(b.charAt(f)==="@"&&(a=t(/^@@?[\w-]+/)))return new e.Variable(a,c)},color:function(){var a;if(b.charAt(f)==="#"&&(a=t(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new e.Color(a[1])},dimension:function(){var a,c=b.charCodeAt(f);if(c>57||c<45||c===47)return;if(a=t(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new e.Dimension(a[1],a[2])},javascript:function(){var a,c=f,d;b.charAt(c)==="~"&&(c++,d=!0);if(b.charAt(c)!=="`")return;d&&t("~");if(a=t(/^`([^`]*)`/))return new e.JavaScript(a[1],f,d)}},variable:function(){var a;if(b.charAt(f)==="@"&&(a=t(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!u(/^[@\w.%-]+\/[@\w.-]+/))return;if((a=t(this.entity))&&t("/")&&(b=t(this.entity)))return new e.Shorthand(a,b)},mixin:{call:function(){var a=[],c,d,g,h=f,i=b.charAt(f)
;if(i!=="."&&i!=="#")return;while(c=t(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))a.push(new e.Element(d,c,f)),d=t(">");t("(")&&(g=t(this.entities.arguments))&&t(")");if(a.length>0&&(t(";")||u("}")))return new e.mixin.Call(a,g,h)},definition:function(){var a,c=[],d,g,h,i;if(b.charAt(f)!=="."&&b.charAt(f)!=="#"||u(/^[^{]*(;|})/))return;if(d=t(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=d[1];while(h=t(this.entities.variable)||t(this.entities.literal)||t(this.entities.keyword)){if(h instanceof e.Variable)if(t(":"))if(i=t(this.expression))c.push({name:h.name,value:i});else throw new Error("Expected value");else c.push({name:h.name});else c.push({value:h});if(!t(","))break}if(!t(")"))throw new Error("Expected )");g=t(this.block);if(g)return new e.mixin.Definition(a,c,g)
}}},entity:function(){return t(this.entities.literal)||t(this.entities.variable)||t(this.entities.url)||t(this.entities.call)||t(this.entities.keyword)||t(this.entities.javascript)||t(this.comment)},end:function(){return t(";")||u("}")},alpha:function(){var a;if(!t(/^\(opacity=/i))return;if(a=t(/^\d+/)||t(this.entities.variable)){if(!t(")"))throw new Error("missing closing ) for alpha()");return new e.Alpha(a)}},element:function(){var a,b,c;c=t(this.combinator),a=t(/^(?:\d+\.\d+|\d+)%/)||t(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||t("*")||t(this.attribute)||t(/^\([^)@]+\)/);if(a)return new e.Element(c,a,f);if(c.value&&c.value.charAt(0)==="&")return new e.Element(c,null,f)},combinator:function(){var a,c=b.charAt(f);if(c===">"||c==="+"||c==="~"){f++;while(b.charAt(f)===" ")f++;return new e.Combinator(c)}if(c==="&"){a="&"
,f++,b.charAt(f)===" "&&(a="& ");while(b.charAt(f)===" ")f++;return new e.Combinator(a)}if(c===":"&&b.charAt(f+1)===":"){f+=2;while(b.charAt(f)===" ")f++;return new e.Combinator("::")}return b.charAt(f-1)===" "?new e.Combinator(" "):new e.Combinator(null)},selector:function(){var a,c,d=[],g,h;while(c=t(this.element)){g=b.charAt(f),d.push(c);if(g==="{"||g==="}"||g===";"||g===",")break}if(d.length>0)return new e.Selector(d)},tag:function(){return t(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||t("*")},attribute:function(){var a="",b,c,d;if(!t("["))return;if(b=t(/^[a-zA-Z-]+/)||t(this.entities.quoted))(d=t(/^[|~*$^]?=/))&&(c=t(this.entities.quoted)||t(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!t("]"))return;if(a)return"["+a+"]"},block:function(){var a;if(t(&quo
t;{")&&(a=t(this.primary))&&t("}"))return a},ruleset:function(){var a=[],b,c,d;q();while(b=t(this.selector)){a.push(b),t(this.comment);if(!t(","))break;t(this.comment)}if(a.length>0&&(c=t(this.block)))return new e.Ruleset(a,c);j=f,r()},rule:function(){var a,c,d=b.charAt(f),h,l;q();if(d==="."||d==="#"||d==="&")return;if(a=t(this.variable)||t(this.property)){a.charAt(0)!="@"&&(l=/^([^@+\/'"*`(;{}-]*);/.exec(k[g]))?(f+=l[0].length-1,c=new e.Anonymous(l[1])):a==="font"?c=t(this.font):c=t(this.value),h=t(this.important);if(c&&t(this.end))return new e.Rule(a,c,h,i);j=f,r()}},"import":function(){var a;if(t(/^@import\s+/)&&(a=t(this.entities.quoted)||t(this.entities.url))&&t(";"))return new e.Import(a,p)},directive:function(){var a,c,d,g;if(b.charAt(f)!=="@")return;if(c=t(this["import"]))return c;if(a=t(/^@medi
a|@page/)||t(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)||t("keyframes")){g=(t(/^[^{]+/)||"").trim();if(d=t(this.block))return new e.Directive(a+" "+g,d)}else if(a=t(/^@[-a-z]+/))if(a==="@font-face"){if(d=t(this.block))return new e.Directive(a,d)}else if((c=t(this.entity))&&t(";"))return new e.Directive(a,c)},font:function(){var a=[],b=[],c,d,f,g;while(g=t(this.shorthand)||t(this.entity))b.push(g);a.push(new e.Expression(b));if(t(","))while(g=t(this.expression)){a.push(g);if(!t(","))break}return new e.Value(a)},value:function(){var a,b=[],c;while(a=t(this.expression)){b.push(a);if(!t(","))break}if(b.length>0)return new e.Value(b)},important:function(){if(b.charAt(f)==="!")return t(/^! *important/)},sub:function(){var a;if(t("(")&&(a=t(this.expression))&&t(")"))return a},multiplication:function(){var a,b,c,d;if(a=t(this.operand)){while(!u(/^\/\*/)&am
p;&(c=t("/")||t("*"))&&(b=t(this.operand)))d=new e.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,c,d,g;if(a=t(this.multiplication)){while((d=t(/^[-+]\s+/)||b.charAt(f-1)!=" "&&(t("+")||t("-")))&&(c=t(this.multiplication)))g=new e.Operation(d,[g||a,c]);return g||a}},operand:function(){var a,c=b.charAt(f+1);b.charAt(f)==="-"&&(c==="@"||c==="(")&&(a=t("-"));var d=t(this.sub)||t(this.entities.dimension)||t(this.entities.color)||t(this.entities.variable)||t(this.entities.call);return a?new e.Operation("*",[new e.Dimension(-1),d]):d},expression:function(){var a,b,c=[],d;while(a=t(this.addition)||t(this.entity))c.push(a);if(c.length>0)return new e.Expression(c)},property:function(){var a;if(a=t(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}};if(d.mode==="browser"||d.mode==="rhino")d.Parser.importer=function(a,b,c,d
){a.charAt(0)!=="/"&&b.length>0&&(a=b[0]+a),n({href:a,title:a,type:d.mime},c,!0)};(function(a){function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function d(a){return Math.min(1,Math.max(0,a))}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){return a=a<0?a+1:a>1?a-1:a,a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(Math.round(b.toHSL(
).h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();return e.s+=c.value/100,e.s=d(e.s),b(e)},desaturate:function(a,c){var e=a.toHSL();return e.s-=c.value/100,e.s=d(e.s),b(e)},lighten:function(a,c){var e=a.toHSL();return e.l+=c.value/100,e.l=d(e.l),b(e)},darken:function(a,c){var e=a.toHSL();return e.l-=c.value/100,e.l=d(e.l),b(e)},fadein:function(a,c){var e=a.toHSL();return e.a+=c.value/100,e.a=d(e.a),b(e)},fadeout:function(a,c){var e=a.toHSL();return e.a-=c.value/100,e.a=d(e.a),b(e)},fade:function(a,c){var e=a.toHSL();return e.a=c.value/100,e.a=d(e.a),b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;return d.h=e<0?360+e:e,b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.r
gb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e<c.length;e++)d=d.replace(/%[sda]/i,function(a){var b=a.match(/s/i)?c[e].value:c[e].toCSS();return a.match(/[A-Z]$/)?encodeURIComponent(b):b});return d=d.replace(/%%/g,"%"),new a.Quoted('"'+d+'"',d)},round:function(a){return this._math("round",a)},ceil:function(a){return this._math("ceil",a)},floor:function(a){return this._math("floor",a)
},_math:function(b,d){if(d instanceof a.Dimension)return new a.Dimension(Math[b](c(d)),d.unit);if(typeof d=="number")return Math[b](d);throw{error:"RuntimeError",message:"math functions take numbers as parameters"}},argb:function(b){return new a.Anonymous(b.toARGB())}}})(c("./tree")),function(a){a.colors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#
008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:&q
uot;#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa
",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"
;#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"}}(c("./tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(a){return this.value.eva
l&&(this.value=this.value.eval(a)),this}}}(c("../tree")),function(a){a.Anonymous=function(a){this.value=a.value||a},a.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Assignment=function(a,b){this.key=a,this.value=b},a.Assignment.prototype={toCSS:function(){return this.key+"="+(this.value.toCSS?this.value.toCSS():this.value)},eval:function(a){return this.value.eval&&(this.value=this.value.eval(a)),this}}}(c("../tree")),function(a){a.Call=function(a,b,c){this.name=a,this.args=b,this.index=c},a.Call.prototype={eval:function(b){var c=this.args.map(function(a){return a.eval(b)});if(!(this.name in a.functions))return new a.Anonymous(this.name+"("+c.map(function(a){return a.toCSS()}).join(", ")+")");try{return a.functions[this.name].apply(a.functions,c)}catch(d){throw{message:"error evaluating function `"+this.name+"`"
,index:this.index}}},toCSS:function(a){return this.eval(a).toCSS()}}}(c("../tree")),function(a){a.Color=function(a,b){Array.isArray(a)?this.rgb=a:a.length==6?this.rgb=a.match(/.{2}/g).map(function(a){return parseInt(a,16)}):this.rgb=a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha=typeof b=="number"?b:1},a.Color.prototype={eval:function(){return this},toCSS:function(){return this.alpha<1?"rgba("+this.rgb.map(function(a){return Math.round(a)}).concat(this.alpha).join(", ")+")":"#"+this.rgb.map(function(a){return a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=
Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);switch(e){case a:g=(b-c)/j+(b<c?6:0);break;case b:g=(c-a)/j+2;break;case c:g=(a-b)/j+4}g/=6}return{h:g*360,s:h,l:i,a:d}},toARGB:function(){var a=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+a.map(function(a){return a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")}}}(c("../tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.va
lue),this.unit||c.unit)}}}(c("../tree")),function(a){a.Directive=function(b,c){this.name=b,Array.isArray(c)?this.ruleset=new a.Ruleset([],c):this.value=c},a.Directive.prototype={toCSS:function(a,b){return this.ruleset?(this.ruleset.root=!0,this.name+(b.compress?"{":" {\n ")+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n ")+(b.compress?"}":"\n}\n")):this.name+" "+this.value.toCSS()+";\n"},eval:function(a){return a.frames.unshift(this),this.ruleset=this.ruleset&&this.ruleset.eval(a),a.frames.shift(),this},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(c("../tree")),function(a){a.Element=function(b,c,d){this.combinator=b instanceof a.Combinator?b:new a.Combinator(b),this.value=c?c.trim():""
;,this.index=d},a.Element.prototype.toCSS=function(a){return this.combinator.toCSS(a||{})+this.value},a.Combinator=function(a){a===" "?this.value=" ":a==="& "?this.value="& ":this.value=a?a.trim():""},a.Combinator.prototype.toCSS=function(a){return{"":""," ":" ","&":"","& ":" ",":":" :","::":"::","+":a.compress?"+":" + ","~":a.compress?"~":" ~ ",">":a.compress?">":" > "}[this.value]}}(c("../tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toC
SS(a)}).join(" ")}}}(c("../tree")),function(a){a.Import=function(b,c){var d=this;this._path=b,b instanceof a.Quoted?this.path=/\.(le?|c)ss(\?.*)?$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value||b.value,this.css=/css(\?.*)?$/.test(this.path),this.css||c.push(this.path,function(a){if(!a)throw new Error("Error parsing "+d.path);d.root=a})},a.Import.prototype={toCSS:function(){return this.css?"@import "+this._path.toCSS()+";\n":""},eval:function(b){var c;if(this.css)return this;c=new a.Ruleset(null,this.root.rules.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));return c.rules}}}(c("../tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,functi
on(c,e){return a.jsify((new a.Variable("@"+e,d.index)).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: `"+f+"`",index:this.index}}for(var h in b.frames[0].variables())e[h.slice(1)]={value:b.frames[0].variables()[h].value,toJS:function(){return this.value.eval(b).toCSS()}};try{c=f.call(e)}catch(g){throw{message:"JavaScript evaluation error: '"+g.name+": "+g.message+"'",index:this.index}}return typeof c=="string"?new a.Quoted('"'+c+'"',c,this.escaped,this.index):Array.isArray(c)?new a.Anonymous(c.join(", ")):new a.Anonymous(c)}}}(c("../tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value}}}(c("../tree")),function(a){a.mixin={},a.mixin.Call=function(b,c,d){this.selector=new a.Selector(b),this.arguments=c,this.index=d},a
.mixin.Call.prototype={eval:function(a){var b,c,d=[],e=!1;for(var f=0;f<a.frames.length;f++)if((b=a.frames[f].find(this.selector)).length>0){c=this.arguments&&this.arguments.map(function(b){return b.eval(a)});for(var g=0;g<b.length;g++)if(b[g].match(c,a))try{Array.prototype.push.apply(d,b[g].eval(a,this.arguments).rules),e=!0}catch(h){throw{message:h.message,index:h.index,stack:h.stack,call:this.index}}if(e)return d;throw{message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(a){return a.toCSS()}).join(", ")+")`",index:this.index}}throw{message:this.selector.toCSS().trim()+" is undefined",index:this.index}}},a.mixin.Definition=function(b,c,d){this.name=b,this.selectors=[new a.Selector([new a.Element(null,b)])],this.params=c,this.arity=c.length,this.rules=d,this._lookups={},this.required=c.reduce(function(a,b){return!b.name||b.name&&!b.value?a+1:a},0),this
.parent=a.Ruleset.prototype,this.frames=[]},a.mixin.Definition.prototype={toCSS:function(){return""},variable:function(a){return this.parent.variable.call(this,a)},variables:function(){return this.parent.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},eval:function(b,c){var d=new a.Ruleset(null,[]),e,f=[];for(var g=0,h;g<this.params.length;g++)if(this.params[g].name)if(h=c&&c[g]||this.params[g].value)d.rules.unshift(new a.Rule(this.params[g].name,h.eval(b)));else throw{message:"wrong number of arguments for "+this.name+" ("+c.length+" for "+this.arity+")"};for(var g=0;g<Math.max(this.params.length,c&&c.length);g++)f.push(c[g]||this.params[g].value);return d.rules.unshift(new a.Rule("@arguments",(new a.Expression(f)).eval(b))),(new a.Ruleset(null,this.rules.slice(0))).eval({frames:[this,d].concat(this.frame
s,b.frames)})},match:function(a,b){var c=a&&a.length||0,d;if(c<this.required)return!1;if(this.required>0&&c>this.params.length)return!1;d=Math.min(c,this.arity);for(var e=0;e<d;e++)if(!this.params[e].name&&a[e].eval(b).toCSS()!=this.params[e].value.eval(b).toCSS())return!1;return!0}}}(c("../tree")),function(a){a.Operation=function(a,b){this.op=a.trim(),this.operands=b},a.Operation.prototype.eval=function(b){var c=this.operands[0].eval(b),d=this.operands[1].eval(b),e;if(c instanceof a.Dimension&&d instanceof a.Color)if(this.op==="*"||this.op==="+")e=d,d=c,c=e;else throw{name:"OperationError",message:"Can't substract or divide a color from a number"};return c.operate(this.op,d)},a.operate=function(a,b,c){switch(a){case"+":return b+c;case"-":return b-c;case"*":return b*c;case"/":return b/c}}}(c("../tree")),function(a){a.Quoted=function(a,b,c,d)
{this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d},a.Quoted.prototype={toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(b){var c=this,d=this.value.replace(/`([^`]+)`/g,function(d,e){return(new a.JavaScript(e,c.index,!0)).eval(b).value}).replace(/@\{([\w-]+)\}/g,function(d,e){var f=(new a.Variable("@"+e,c.index)).eval(b);return f.value||f.toCSS()});return new a.Quoted(this.quote+d+this.quote,d,this.escaped,this.index
+)}}}(c("../tree")),function(a){a.Rule=function(b,c,d,e){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.index=e,b.charAt(0)==="@"?this.variable=!0:this.variable=!1},a.Rule.prototype.toCSS=function(a){return this.variable?"":this.name+(a.compress?":":": ")+this.value.toCSS(a)+this.important+";"},a.Rule.prototype.eval=function(b){return new a.Rule(this.name,this.value.eval(b),this.important,this.index)},a.Shorthand=function(a,b){this.a=a,this.b=b},a.Shorthand.prototype={toCSS:function(a){return this.a.toCSS(a)+"/"+this.b.toCSS(a)},eval:function(){return this}}}(c("../tree")),function(a){a.Ruleset=function(a,b){this.selectors=a,this.rules=b,this._lookups={}},a.Ruleset.prototype={eval:function(b){var c=new a.Ruleset(this.selectors,this.rules.slice(0));c.root=this.root,b.frames.unshift(c);if(c.root)for(var d=0;d<c.rules.length;d++)c.r
ules[d]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Definition&&(c.rules[d].frames=b.frames.slice(0));for(var d=0;d<c.rules.length;d++)c.rules[d]instanceof a.mixin.Call&&Array.prototype.splice.apply(c.rules,[d,1].concat(c.rules[d].eval(b)));for(var d=0,e;d<c.rules.length;d++)e=c.rules[d],e instanceof a.mixin.Definition||(c.rules[d]=e.eval?e.eval(b):e);return b.frames.shift(),c},match:function(a){return!a||a.length===0},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(b,c){return c instanceof a.Rule&&c.variable===!0&&(b[c.name]=c),b},{})},variable:function(a){return this.variables()[a]},rulesets:function(){return this._rulesets?this._rulesets:this._rulesets=this.rules.filter(function(b){return b instanceof a.Ruleset||b instanceof a.mixin.Definition})},find:function(b,c){c=c||
this;var d=[],e,f,g=b.toCSS();return g in this._lookups?this._lookups[g]:(this.rulesets().forEach(function(e){if(e!==c)for(var g=0;g<e.selectors.length;g++)if(f=b.match(e.selectors[g])){b.elements.length>e.selectors[g].elements.length?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}}),this._lookups[g]=d)},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;this.root||(b.length===0?g=this.selectors.map(function(a){return[a]}):this.joinSelectors(g,b,this.selectors));for(var j=0;j<this.rules.length;j++)i=this.rules[j],i.rules||i instanceof a.Directive?f.push(i.toCSS(g,c)):i instanceof a.Comment?i.silent||(this.root?f.push(i.toCSS(c)):e.push(i.toCSS(c))):i.toCSS&&!i.variable?e.push(i.toCSS(c)):i.value&&!i.variable&&e.push(i.value.toString());return f=f.join(""),this.root?d.push(e.join(c.compress?"":"\n")):e.length>0&&(h=g.map(function(a){return a.map(function(a){return a.toC
SS(c)}).join("").trim()}).join(c.compress?",":g.length>3?",\n":", "),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f),d.join("")+(c.compress?"\n":"")},joinSelectors:function(a,b,c){for(var d=0;d<c.length;d++)this.joinSelector(a,b,c[d])},joinSelector:function(b,c,d){var e=[],f=[],g=[],h=[],i=!1,j;for(var k=0;k<d.elements.length;k++)j=d.elements[k],j.combinator.value.charAt(0)==="&"&&(i=!0),i?h.push(j):g.push(j);i||(h=g,g=[]),g.length>0&&e.push(new a.Selector(g)),h.length>0&&f.push(new a.Selector(h));for(var l=0;l<c.length;l++)b.push(e.concat(c[l]).concat(f))}}}(c("../tree")),function(a){a.Selector=function(a){this.elements=a,this.elements[0].combinator.value===""&&(this.elements[0].combinator.value=" ")},a.Select
or.prototype.match=function(a){var b=this.elements.length,c=a.elements.length,d=Math.min(b,c);if(b<c)return!1;for(var e=0;e<d;e++)if(this.elements[e].value!==a.elements[e].value)return!1;return!0},a.Selector.prototype.toCSS=function(a){return this._css?this._css:this._css=this.elements.map(function(b){return typeof b=="string"?" "+b.trim():b.toCSS(a)}).join("")}}(c("../tree")),function(b){b.URL=function(b,c){b.data?this.attrs=b:(typeof a!="undefined"&&!/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(b.value)&&c.length>0&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("../tr
ee")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("../tree")),function(a){a.Variable=function(a,b){this.name=a,this.index=b},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{message:"variable "+e+" is undefined",index:this.index}}}}(c("../tree")),c("./tree").find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null},c("./tree").jsify=function(a){return Array.isArray(a.value)&&a.value.leng
th>1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)};var f=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||f?"development":"production"),d.async=!1,d.poll=d.poll||(f?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&m(function(a,b,c){a&&p(a.toCSS(),b,c.lastModified)})},d.poll)):d.optimization=3;var g;try{g=typeof a.localStorage=="undefined"?null:a.localStorage}catch(h){g=null}var i=document.getEle
mentsByTagName("link"),j=/^text\/(x-)?less$/;d.sheets=[];for(var k=0;k<i.length;k++)(i[k].rel==="stylesheet/less"||i[k].rel.match(/stylesheet/)&&i[k].type.match(j))&&d.sheets.push(i[k]);d.refresh=function(a){var b,c;b=c=new Date,m(function(a,d,e){e.local?t("loading "+d.href+" from cache."):(t("parsed "+d.href+" successfully."),p(a.toCSS(),d,e.lastModified)),t("css for "+d.href+" generated in "+(new Date-c)+"ms"),e.remaining===0&&t("css generated in "+(new Date-b)+"ms"),c=new Date},a),l()},d.refreshStyles=l,d.refresh(d.env==="development")})(window);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless120js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.0.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.0.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.0.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3293 @@
</span><ins>+//
+// LESS - Leaner CSS v1.2.0
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+ // Rhino
+ // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+ if (typeof(window) === 'undefined') { less = {} }
+ else { less = window.less = {} }
+ tree = less.tree = {};
+ less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+ // Node.js
+ less = exports,
+ tree = require('./tree');
+ less.mode = 'node';
+} else {
+ // Browser
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+ less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ mime: env && env.mime, // MIME type of .less files
+ error: null, // Error in parsing/evaluating an import
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (e, root) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+
+ if (e && !that.error) { that.error = e }
+ callback(e, root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ function expect(arg, msg) {
+ var result = $(arg);
+ if (! result) {
+ error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+ : "unexpected token"));
+ } else {
+ return result;
+ }
+ }
+
+ function error(msg, type) {
+ throw { index: i, type: type || 'Syntax', message: msg };
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ function getLocation(index) {
+ for (var n = index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ return { line: index ? (input.slice(0, index).match(/\n/g) || "").length : null,
+ column: column };
+ }
+
+ function LessError(e, env) {
+ var lines = input.split('\n'),
+ loc = getLocation(e.index),
+ line = loc.line,
+ col = loc.column;
+
+ this.type = e.type || 'SyntaxError';
+ this.message = e.message;
+ this.filename = e.filename || env.filename;
+ this.index = e.index;
+ this.line = typeof(line) === 'number' ? line + 1 : null;
+ this.callLine = e.call && (getLocation(e.call) + 1);
+ this.callExtract = lines[getLocation(e.call)];
+ this.stack = e.stack;
+ this.column = col;
+ this.extract = [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ];
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ chunks = [];
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam,
+ inString;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = i;
+
+ if (!inString && !inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ if (c === '{' && !inString && !inParam) { level ++;
+ chunk.push(c);
+ } else if (c === '}' && !inString && !inParam) { level --;
+ chunk.push(c);
+ chunks[++j] = chunk = [];
+ } else if (c === '(' && !inString && !inParam) {
+ chunk.push(c);
+ inParam = true;
+ } else if (c === ')' && !inString && inParam) {
+ chunk.push(c);
+ inParam = false;
+ } else {
+ if (c === '"' || c === "'" || c === '`') {
+ if (! inString) {
+ inString = c;
+ } else {
+ inString = inString === c ? false : inString;
+ }
+ }
+ chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ throw {
+ type: 'Syntax',
+ message: "Missing closing `}`",
+ filename: env.filename
+ };
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ try {
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+ } catch (e) {
+ return callback(new(LessError)(e, env));
+ }
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [];
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ throw new(LessError)(e, env);
+ }
+
+ if (parser.imports.error) { throw parser.imports.error }
+
+ if (options.yuicompress && less.mode === 'node') {
+ return require('./cssmin').compressor.cssmin(css);
+ } else if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ type: "Parse",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+
+ if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+ if (tree.colors.hasOwnProperty(k)) {
+ // detect named color
+ return new(tree.Color)(tree.colors[k].slice(1));
+ } else {
+ return new(tree.Keyword)(k);
+ }
+ }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args, index = i;
+
+ if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args, index) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.entities.assignment) || $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ // Assignments are argument entities for calls.
+ // They are present in ie filter properties as shown below.
+ //
+ // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+ //
+
+ assignment: function () {
+ var key, value;
+ if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+ return new(tree.Assignment)(key, value);
+ }
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+
+ expect(')');
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i), important = false;
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e, i));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if ($(this.important)) {
+ important = true;
+ }
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index, important);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value, cond;
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ save();
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ while (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ value = expect(this.expression, 'expected expression');
+ params.push({ name: param.name, value: value });
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ if (! $(',')) { break }
+ }
+ expect(')');
+
+ if ($(/^when/)) { // Guard
+ cond = expect(this.conditions, 'expected condition');
+ }
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset, cond);
+ } else {
+ restore();
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^\(opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ expect(')');
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c, v;
+
+ c = $(this.combinator);
+ e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+ $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+ if (! e) {
+ $('(') && (v = $(this.entities.variable)) && $(')') && (e = new(tree.Paren)(v));
+ }
+
+ if (e) { return new(tree.Element)(c, e, i) }
+
+ if (c.value && c.value.charAt(0) === '&') {
+ return new(tree.Element)(c, null, i);
+ }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === '&') {
+ match = '&';
+ i++;
+ if(input.charAt(i) === ' ') {
+ match = '& ';
+ }
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(match);
+ } else if (c === ':' && input.charAt(i + 1) === ':') {
+ i += 2;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)('::');
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path, features;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url))) {
+ features = $(this.mediaFeatures);
+ if ($(';')) {
+ return new(tree.Import)(path, imports, features);
+ }
+ }
+ },
+
+ mediaFeature: function () {
+ var nodes = [];
+
+ do {
+ if (e = $(this.entities.keyword)) {
+ nodes.push(e);
+ } else if ($('(')) {
+ p = $(this.property);
+ e = $(this.entity);
+ if ($(')')) {
+ if (p && e) {
+ nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+ } else if (e) {
+ nodes.push(new(tree.Paren)(e));
+ } else {
+ return null;
+ }
+ } else { return null }
+ }
+ } while (e);
+
+ if (nodes.length > 0) {
+ return new(tree.Expression)(nodes);
+ }
+ },
+
+ mediaFeatures: function () {
+ var f, features = [];
+ while (f = $(this.mediaFeature)) {
+ features.push(f);
+ if (! $(',')) { break }
+ }
+ return features.length > 0 ? features : null;
+ },
+
+ media: function () {
+ var features;
+
+ if ($(/^@media/)) {
+ features = $(this.mediaFeatures);
+
+ if (rules = $(this.block)) {
+ return new(tree.Directive)('@media', rules, features);
+ }
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types, e, nodes;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import']) || $(this.media)) {
+ return value;
+ } else if (name = $(/^@page|@keyframes/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ conditions: function () {
+ var a, b, index = i, condition;
+
+ if (a = $(this.condition)) {
+ while ($(',') && (b = $(this.condition))) {
+ condition = new(tree.Condition)('or', condition || a, b, index);
+ }
+ return condition || a;
+ }
+ },
+ condition: function () {
+ var a, b, c, op, index = i, negate = false;
+
+ if ($(/^not/)) { negate = true }
+ expect('(');
+ if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+ if (op = $(/^(?:>=|=<|[<=>])/)) {
+ if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+ c = new(tree.Condition)(op, a, b, index, negate);
+ } else {
+ error('expected expression');
+ }
+ } else {
+ c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+ }
+ expect(')');
+ return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (path.charAt(0) !== '/' && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fade: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a = amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ return this._math('round', n);
+ },
+ ceil: function (n) {
+ return this._math('ceil', n);
+ },
+ floor: function (n) {
+ return this._math('floor', n);
+ },
+ _math: function (fn, n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math[fn](n);
+ } else {
+ throw { type: "Argument", message: "argument must be a number" };
+ }
+ },
+ argb: function (color) {
+ return new(tree.Anonymous)(color.toARGB());
+
+ },
+ percentage: function (n) {
+ return new(tree.Dimension)(n.value * 100, '%');
+ },
+ color: function (n) {
+ if (n instanceof tree.Quoted) {
+ return new(tree.Color)(n.value.slice(1));
+ } else {
+ throw { type: "Argument", message: "argument must be a string" };
+ }
+ },
+ iscolor: function (n) {
+ return this._isa(n, tree.Color);
+ },
+ isnumber: function (n) {
+ return this._isa(n, tree.Dimension);
+ },
+ isstring: function (n) {
+ return this._isa(n, tree.Quoted);
+ },
+ iskeyword: function (n) {
+ return this._isa(n, tree.Keyword);
+ },
+ isurl: function (n) {
+ return this._isa(n, tree.URL);
+ },
+ ispixel: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+ },
+ ispercentage: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+ },
+ isem: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+ },
+ _isa: function (n, Type) {
+ return (n instanceof Type) ? tree.True : tree.False;
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+ tree.colors = {
+ 'aliceblue':'#f0f8ff',
+ 'antiquewhite':'#faebd7',
+ 'aqua':'#00ffff',
+ 'aquamarine':'#7fffd4',
+ 'azure':'#f0ffff',
+ 'beige':'#f5f5dc',
+ 'bisque':'#ffe4c4',
+ 'black':'#000000',
+ 'blanchedalmond':'#ffebcd',
+ 'blue':'#0000ff',
+ 'blueviolet':'#8a2be2',
+ 'brown':'#a52a2a',
+ 'burlywood':'#deb887',
+ 'cadetblue':'#5f9ea0',
+ 'chartreuse':'#7fff00',
+ 'chocolate':'#d2691e',
+ 'coral':'#ff7f50',
+ 'cornflowerblue':'#6495ed',
+ 'cornsilk':'#fff8dc',
+ 'crimson':'#dc143c',
+ 'cyan':'#00ffff',
+ 'darkblue':'#00008b',
+ 'darkcyan':'#008b8b',
+ 'darkgoldenrod':'#b8860b',
+ 'darkgray':'#a9a9a9',
+ 'darkgrey':'#a9a9a9',
+ 'darkgreen':'#006400',
+ 'darkkhaki':'#bdb76b',
+ 'darkmagenta':'#8b008b',
+ 'darkolivegreen':'#556b2f',
+ 'darkorange':'#ff8c00',
+ 'darkorchid':'#9932cc',
+ 'darkred':'#8b0000',
+ 'darksalmon':'#e9967a',
+ 'darkseagreen':'#8fbc8f',
+ 'darkslateblue':'#483d8b',
+ 'darkslategray':'#2f4f4f',
+ 'darkslategrey':'#2f4f4f',
+ 'darkturquoise':'#00ced1',
+ 'darkviolet':'#9400d3',
+ 'deeppink':'#ff1493',
+ 'deepskyblue':'#00bfff',
+ 'dimgray':'#696969',
+ 'dimgrey':'#696969',
+ 'dodgerblue':'#1e90ff',
+ 'firebrick':'#b22222',
+ 'floralwhite':'#fffaf0',
+ 'forestgreen':'#228b22',
+ 'fuchsia':'#ff00ff',
+ 'gainsboro':'#dcdcdc',
+ 'ghostwhite':'#f8f8ff',
+ 'gold':'#ffd700',
+ 'goldenrod':'#daa520',
+ 'gray':'#808080',
+ 'grey':'#808080',
+ 'green':'#008000',
+ 'greenyellow':'#adff2f',
+ 'honeydew':'#f0fff0',
+ 'hotpink':'#ff69b4',
+ 'indianred':'#cd5c5c',
+ 'indigo':'#4b0082',
+ 'ivory':'#fffff0',
+ 'khaki':'#f0e68c',
+ 'lavender':'#e6e6fa',
+ 'lavenderblush':'#fff0f5',
+ 'lawngreen':'#7cfc00',
+ 'lemonchiffon':'#fffacd',
+ 'lightblue':'#add8e6',
+ 'lightcoral':'#f08080',
+ 'lightcyan':'#e0ffff',
+ 'lightgoldenrodyellow':'#fafad2',
+ 'lightgray':'#d3d3d3',
+ 'lightgrey':'#d3d3d3',
+ 'lightgreen':'#90ee90',
+ 'lightpink':'#ffb6c1',
+ 'lightsalmon':'#ffa07a',
+ 'lightseagreen':'#20b2aa',
+ 'lightskyblue':'#87cefa',
+ 'lightslategray':'#778899',
+ 'lightslategrey':'#778899',
+ 'lightsteelblue':'#b0c4de',
+ 'lightyellow':'#ffffe0',
+ 'lime':'#00ff00',
+ 'limegreen':'#32cd32',
+ 'linen':'#faf0e6',
+ 'magenta':'#ff00ff',
+ 'maroon':'#800000',
+ 'mediumaquamarine':'#66cdaa',
+ 'mediumblue':'#0000cd',
+ 'mediumorchid':'#ba55d3',
+ 'mediumpurple':'#9370d8',
+ 'mediumseagreen':'#3cb371',
+ 'mediumslateblue':'#7b68ee',
+ 'mediumspringgreen':'#00fa9a',
+ 'mediumturquoise':'#48d1cc',
+ 'mediumvioletred':'#c71585',
+ 'midnightblue':'#191970',
+ 'mintcream':'#f5fffa',
+ 'mistyrose':'#ffe4e1',
+ 'moccasin':'#ffe4b5',
+ 'navajowhite':'#ffdead',
+ 'navy':'#000080',
+ 'oldlace':'#fdf5e6',
+ 'olive':'#808000',
+ 'olivedrab':'#6b8e23',
+ 'orange':'#ffa500',
+ 'orangered':'#ff4500',
+ 'orchid':'#da70d6',
+ 'palegoldenrod':'#eee8aa',
+ 'palegreen':'#98fb98',
+ 'paleturquoise':'#afeeee',
+ 'palevioletred':'#d87093',
+ 'papayawhip':'#ffefd5',
+ 'peachpuff':'#ffdab9',
+ 'peru':'#cd853f',
+ 'pink':'#ffc0cb',
+ 'plum':'#dda0dd',
+ 'powderblue':'#b0e0e6',
+ 'purple':'#800080',
+ 'red':'#ff0000',
+ 'rosybrown':'#bc8f8f',
+ 'royalblue':'#4169e1',
+ 'saddlebrown':'#8b4513',
+ 'salmon':'#fa8072',
+ 'sandybrown':'#f4a460',
+ 'seagreen':'#2e8b57',
+ 'seashell':'#fff5ee',
+ 'sienna':'#a0522d',
+ 'silver':'#c0c0c0',
+ 'skyblue':'#87ceeb',
+ 'slateblue':'#6a5acd',
+ 'slategray':'#708090',
+ 'slategrey':'#708090',
+ 'snow':'#fffafa',
+ 'springgreen':'#00ff7f',
+ 'steelblue':'#4682b4',
+ 'tan':'#d2b48c',
+ 'teal':'#008080',
+ 'thistle':'#d8bfd8',
+ 'tomato':'#ff6347',
+ 'turquoise':'#40e0d0',
+ 'violet':'#ee82ee',
+ 'wheat':'#f5deb3',
+ 'white':'#ffffff',
+ 'whitesmoke':'#f5f5f5',
+ 'yellow':'#ffff00',
+ 'yellowgreen':'#9acd32'
+ };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+ this.key = key;
+ this.value = val;
+};
+tree.Assignment.prototype = {
+ toCSS: function () {
+ return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+ this.name = name;
+ this.args = args;
+ this.index = index;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ try {
+ return tree.functions[this.name].apply(tree.functions, args);
+ } catch (e) {
+ throw { type: e.type || "Runtime",
+ message: "error evaluating function `" + this.name + "`" +
+ (e.message ? ': ' + e.message : ''),
+ index: this.index };
+ }
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ },
+ toARGB: function () {
+ var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+ return '#' + argb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+ this.op = op.trim();
+ this.lvalue = l;
+ this.rvalue = r;
+ this.index = i;
+ this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+ var a = this.lvalue.eval(env),
+ b = this.rvalue.eval(env);
+
+ var i = this.index, result
+
+ var result = (function (op) {
+ switch (op) {
+ case 'and':
+ return a && b;
+ case 'or':
+ return a || b;
+ default:
+ if (a.compare) {
+ result = a.compare(b);
+ } else if (b.compare) {
+ result = b.compare(a);
+ } else {
+ throw { type: "Type",
+ message: "Unable to perform comparison",
+ index: i };
+ }
+ switch (result) {
+ case -1: return op === '<' || op === '=<';
+ case 0: return op === '=' || op === '>=' || op === '=<';
+ case 1: return op === '>' || op === '>=';
+ }
+ }
+ })(this.op);
+ return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ },
+
+ // TODO: Perform unit conversion before comparing
+ compare: function (other) {
+ if (other instanceof tree.Dimension) {
+ if (other.value > this.value) {
+ return -1;
+ } else if (other.value < this.value) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ return -1;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value, features) {
+ this.name = name;
+ this.features = features && new(tree.Value)(features);
+
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ this.ruleset.allowImports = true;
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + features + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ this.features = this.features && this.features.eval(env);
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+
+ if (typeof(value) === 'string') {
+ this.value = value.trim();
+ } else if (value) {
+ this.value = value;
+ } else {
+ this.value = "";
+ }
+ this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+ return new(tree.Element)(this.combinator,
+ this.value.eval ? this.value.eval(env) : this.value,
+ this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + (this.value.toCSS ? this.value.toCSS(env) : this.value);
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else if (value === '& ') {
+ this.value = '& ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ '& ' : ' ',
+ ':' : ' :',
+ '::': '::',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS ? e.toCSS(env) : '';
+ }).join(' ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features) {
+ var that = this;
+
+ this._path = path;
+ this.features = features && new(tree.Value)(features);
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css(\?.*)?$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (e, root) {
+ that.root = root;
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function (env) {
+ var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+ if (this.css) {
+ return "@import " + this._path.toCSS() + features + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset, features = this.features && this.features.eval(env);
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return this.features ? new(tree.Directive)('@media', ruleset.rules, this.features.value) : ruleset.rules;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value },
+ compare: function (other) {
+ if (other instanceof tree.Keyword) {
+ return other.value === this.value ? 0 : 1;
+ } else {
+ return -1;
+ }
+ }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, important) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+ this.important = important;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments, this.important).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { type: 'Runtime',
+ message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index };
+ }
+ }
+ }
+ throw { type: 'Name',
+ message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.condition = condition;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ evalParams: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []);
+
+ for (var i = 0, val; i < this.params.length; i++) {
+ if (this.params[i].name) {
+ if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+ } else {
+ throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ return frame;
+ },
+ eval: function (env, args, important) {
+ var frame = this.evalParams(env, args), context, _arguments = [], rules;
+
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ rules = important ?
+ this.rules.map(function (r) {
+ return new(tree.Rule)(r.name, r.value, '!important', r.index);
+ }) : this.rules.slice(0);
+
+ return new(tree.Ruleset)(null, rules).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len, frame;
+
+ if (argsLength < this.required) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+ if (this.condition && !this.condition.eval({
+ frames: [this.evalParams(env, args)].concat(env.frames)
+ })) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+ this.value = node;
+};
+tree.Paren.prototype = {
+ toCSS: function (env) {
+ return '(' + this.value.toCSS(env) + ')';
+ },
+ eval: function (env) {
+ return new(tree.Paren)(this.value.eval(env));
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return ('value' in v) ? v.value : v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+ this.inline = inline || false;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + (this.inline ? "" : ";");
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name,
+ this.value.eval(context),
+ this.important,
+ this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+ var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0));
+
+ ruleset.root = this.root;
+ ruleset.allowImports = this.allowImports;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root || ruleset.allowImports) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > rule.selectors[j].elements.length) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ this.joinSelectors(paths, context, this.selectors);
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ },
+
+ joinSelectors: function (paths, context, selectors) {
+ for (var s = 0; s < selectors.length; s++) {
+ this.joinSelector(paths, context, selectors[s]);
+ }
+ },
+
+ joinSelector: function (paths, context, selector) {
+ var before = [], after = [], beforeElements = [],
+ afterElements = [], hasParentSelector = false, el;
+
+ for (var i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ if (el.combinator.value.charAt(0) === '&') {
+ hasParentSelector = true;
+ }
+ if (hasParentSelector) afterElements.push(el);
+ else beforeElements.push(el);
+ }
+
+ if (! hasParentSelector) {
+ afterElements = beforeElements;
+ beforeElements = [];
+ }
+
+ if (beforeElements.length > 0) {
+ before.push(new(tree.Selector)(beforeElements));
+ }
+
+ if (afterElements.length > 0) {
+ after.push(new(tree.Selector)(afterElements));
+ }
+
+ for (var c = 0; c < context.length; c++) {
+ paths.push(before.concat(context[c]).concat(after));
+ }
+ }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ var len = this.elements.length,
+ olen = other.elements.length,
+ max = Math.min(len, olen);
+
+ if (len < olen) {
+ return false;
+ } else {
+ for (var i = 0; i < max; i++) {
+ if (this.elements[i].value !== other.elements[i].value) {
+ return false;
+ }
+ }
+ }
+ return true;
+};
+tree.Selector.prototype.eval = function (env) {
+ return new(tree.Selector)(this.elements.map(function (e) {
+ return e.eval(env);
+ }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (typeof(window) !== 'undefined' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { message: "variable " + name + " is undefined",
+ index: this.index };
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+tree.jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+
+})(require('./tree'));
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:' ||
+ location.protocol === 'chrome:' ||
+ location.protocol === 'chrome-extension:' ||
+ location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (root, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (root, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+ var css = tree.toCSS();
+ var style = styles[i];
+ style.type = 'text/css';
+ if (style.styleSheet) {
+ style.styleSheet.cssText = css;
+ } else {
+ style.innerHTML = css;
+ }
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^(https?|file):/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ css.media = sheet.media || 'screen';
+ css.id = id;
+ document.getElementsByTagName('head')[0].appendChild(css);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? false : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol) {
+ if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+
+ var template = ['<ul>',
+ '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+ '<li><label>[0]</label><pre>{current}</pre></li>',
+ '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+ '</ul>'].join('\n');
+
+ var elem = document.createElement('div'), timer, content;
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p><a href="' + href + '">' + href + "</a> ";
+
+ if (e.extract) {
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ template.replace(/\[(-?\d)\]/g, function (_, i) {
+ return (parseInt(e.line) + parseInt(i)) || '';
+ }).replace(/\{(\d)\}/g, function (_, i) {
+ return e.extract[parseInt(i)] || '';
+ }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+ e.extract[1].slice(e.column) + '</span>');
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #ee4444;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.ctx {',
+ 'color: #dd4444;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless120minjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.0.min.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.0.min.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.0.min.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+//
+// LESS - Leaner CSS v1.2.0
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function c(b){return a.less[b.split("/")[1]]}function m(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(k)&&(new d.Parser).parse(a[b].innerHTML||"",function(c,d){var e=d.toCSS(),f=a[b];f.type="text/css",f.styleSheet?f.styleSheet.cssText=e:f.innerHTML=e})}function n(a,b){for(var c=0;c<d.sheets.length;c++)o(d.sheets[c],a,b,d.sheets.length-(c+1))}function o(b,c,e,f){var g=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/,""),j=h&&h.getItem(i),k=h&&h.getItem(i+":timestamp"),l={css:j,timestamp:k};/^(https?|file):/.test(i)||(i.charAt(0)=="/"?i=a.location.protocol+"//"+a.location.host+i:i=g.slice(0,g.lastIndexOf("/")+1)+i),s(b.href,b.type,function(a,g){if(!e&&l&&g&&(new Date(g)).valueOf()===(new Date(l.timestamp)).valueOf())r(l.css,b),c(null,b,{local:!0,remaining:f});el
se try{(new d.Parser({optimization:d.optimization,paths:[i.replace(/[\w\.-]+$/,"")],mime:b.type})).parse(a,function(a,d){if(a)return w(a,i);try{c(d,b,{local:!1,lastModified:g,remaining:f}),u(document.getElementById("less-error-message:"+q(i)))}catch(a){w(a,i)}})}catch(h){w(h,i)}},function(a,b){throw new Error("Couldn't load "+b+" ("+a+")")})}function q(a){return a.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\?.*$/,"").replace(/\.[^\.\/]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function r(a,b,c){var d,e=b.href?b.href.replace(/\?.*$/,""):"",f="less:"+(b.title||q(e));(d=document.getElementById(f))===null&&(d=document.createElement("style"),d.type="text/css",d.media=b.media||"screen",d.id=f,document.getElementsByTagName("head")[0].appendChild(d));if(d.styleSheet)try{d.styleS
heet.cssText=a}catch(g){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(a){d.childNodes.length>0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&h&&(v("saving "+e+" to cache."),h.setItem(e,a),h.setItem(e+":timestamp",c))}function s(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var f=t(),h=g?!1:d.async;typeof f.overrideMimeType=="function"&&f.overrideMimeType("text/css"),f.open("GET",a,h),f.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),f.send(null),g?f.status===0||f.status>=200&&f.status<300?c(f.responseText):e(f.status,a):h?f.onreadystatechange=function(){f.readyState==4&&i(f,c,e)
}:i(f,c,e)}function t(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){return v("browser doesn't support AJAX."),null}}function u(a){return a&&a.parentNode.removeChild(a)}function v(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: "+a)}function w(a,b){var c="less-error-message:"+q(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less f
ile")+"</h3>"+'<p><a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+":</p>"+e.replace(/\[(-?\d)\]/g,function(b,c){return parseInt(a.line)+parseInt(c)||""}).replace(/\{(\d)\}/g,function(b,c){return a.extract[parseInt(c)]||""}).replace(/\{current\}/,a.extract[1].slice(0,a.column)+'<span class="error">'+a.extract[1].slice(a.column)+"</span>")),f.innerHTML=h,r([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #ee4444;","padding: 4
px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.ctx {","color: #dd4444;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.en
v=="development"&&(g=setInterval(function(){document.body&&(document.getElementById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d<c;d++)d in this&&a.call(b,this[d],d,this)}),Array.prototype.map||(Array.prototype.map=function(a){var b=this.length>>>0,c=new Array(b),d=arguments[1];for(var e=0;e<b;e++)e in this&&(c[e]=a.call(d,this[e],e,this));return c}),Array.prototype.filter||(Array.prototype.filter=function(a){var b=[],c=arguments[1];for(var d=0;d<this.length;d++)a.call(c,this[d])&&b.push(this[d]);return b}),Array.prototype.reduce||(Array.prototype.reduce=function(a){var b=this.length&g
t;>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.length>=2)var d=arguments[1];else do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0);for(;c<b;c++)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){var b=this.length,c=arguments[1]||0;if(!b)return-1;if(c>=b)return-1;c<0&&(c+=b);for(;c<b;c++){if(!Object.prototype.hasOwnProperty.call(this,c))continue;if(a===this[c])return c}return-1}),Object.keys||(Object.keys=function(a){var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}),String.prototype.trim||(String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")});var d,f;typeof environment=="object"&&{}.toString.call(environment)==="[object Environment]"?(typeof a=="undefined"?d={}:d=a.less={},f=
d.tree={},d.mode="rhino"):typeof a=="undefined"?(d=exports,f=c("./tree"),d.mode="node"):(typeof a.less=="undefined"&&(a.less={}),d=a.less,f=a.less.tree={},d.mode="browser"),d.Parser=function x(a){function s(){i=l[h],j=g,m=g}function t(){l[h]=i,g=j,m=g}function u(){g>m&&(l[h]=l[h].slice(g-m),m=g)}function v(a){var c,d,e,f,i,j,k,o;if(a instanceof Function)return a.call(n.parsers);if(typeof a=="string")c=b.charAt(g)===a?a:null,e=1,u();else{u();if(c=a.exec(l[h]))e=c[0].length;else return null}if(c){o=g+=e,j=g+l[h].length-e;while(g<j){f=b.charCodeAt(g);if(f!==32&&f!==10&&f!==9)break;g++}return l[h]=l[h].slice(e+(g-o)),m=g,l[h].length===0&&h<l.length-1&&h++,typeof c=="string"?c:c.length===1?c[0]:c}}function w(a,c){var d=v(a);if(!d)x(c||(typeof a=="string"?"expected '"+a+"' got '"+b.charAt(g)+"'":"unexpected to
ken"));else return d}function x(a,b){throw{index:g,type:b||"Syntax",message:a}}function y(a){return typeof a=="string"?b.charAt(g)===a:a.test(l[h])?!0:!1}function z(a){for(var c=a,d=-1;c>=0&&b.charAt(c)!=="\n";c--)d++;return{line:a?(b.slice(0,a).match(/\n/g)||"").length:null,column:d}}function A(a,c){var d=b.split("\n"),e=z(a.index),f=e.line,g=e.column;this.type=a.type||"SyntaxError",this.message=a.message,this.filename=a.filename||c.filename,this.index=a.index,this.line=typeof f=="number"?f+1:null,this.callLine=a.call&&z(a.call)+1,this.callExtract=d[z(a.call)],this.stack=a.stack,this.column=g,this.extract=[d[f-1],d[f],d[f+1]]}var b,g,h,i,j,k,l,m,n,o=this,q=function(){},r=this.imports={paths:a&&a.paths||[],queue:[],files:{},mime:a&&a.mime,error:null,push:function(b,c){var e=this;this.queue.push(b),d.Parser.importer(b,this.paths,function(a,d){e.queue.splice(e.queue.indexOf(b)
,1),e.files[b]=d,a&&!e.error&&(e.error=a),c(a,d),e.queue.length===0&&q()},a)}};return this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.filename=this.env.filename||null,n={imports:r,parse:function(e,i){var j,o,p,r,s,t,u=[],w,x=null;g=h=m=k=0,l=[],b=e.replace(/\r\n/g,"\n"),l=function(c){var d=0,e=/[^"'`\{\}\/\(\)]+/g,f=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,g=0,h,i=c[0],j,k;for(var l=0,m,n;l<b.length;l++){e.lastIndex=l,(h=e.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0])),m=b.charAt(l),f.lastIndex=l,!k&&!j&&m==="/"&&(n=b.charAt(l+1),(n==="/"||n==="*")&&(h=f.exec(b))&&h.index===l&&(l+=h[0].length,i.push(h[0]),m=b.charAt(l)));if(m==="{"&&!k&&!j)g++,i.push(m);else if(m==="}"&&!k&&!j)g--,i.push(m),c[++d]=i=[];else if(m==="("&&!k
&&!j)i.push(m),j=!0;else if(m===")"&&!k&&j)i.push(m),j=!1;else{if(m==='"'||m==="'"||m==="`")k?k=k===m?!1:k:k=m;i.push(m)}}if(g>0)throw{type:"Syntax",message:"Missing closing `}`",filename:a.filename};return c.map(function(a){return a.join("")})}([[]]);try{j=new f.Ruleset([],v(this.parsers.primary)),j.root=!0}catch(y){return i(new A(y,a))}j.toCSS=function(b){var e,g,h;return function(e,g){var h=[];e=e||{},typeof g=="object"&&!Array.isArray(g)&&(g=Object.keys(g).map(function(a){var b=g[a];return b instanceof f.Value||(b instanceof f.Expression||(b=new f.Expression([b])),b=new f.Value([b])),new f.Rule("@"+a,b,!1,0)}),h=[new f.Ruleset(null,g)]);try{var i=b.call(this,{frames:h}).toCSS([],{compress:e.compress||!1})}catch(j){throw new A(j,a)}if(n.imports.error)throw n.imports.error;return e.yuicompress&&d.mode==="node"?c("./cssmin").com
pressor.cssmin(i):e.compress?i.replace(/(\s)+/g,"$1"):i}}(j.eval);if(g<b.length-1){g=k,t=b.split("\n"),s=(b.slice(0,g).match(/\n/g)||"").length+1;for(var z=g,B=-1;z>=0&&b.charAt(z)!=="\n";z--)B++;x={type:"Parse",message:"Syntax Error on line "+s,index:g,filename:a.filename,line:s,column:B,extract:[t[s-2],t[s-1],t[s]]}}this.imports.queue.length>0?q=function(){i(x,j)}:i(x,j)},parsers:{primary:function(){var a,b=[];while((a=v(this.mixin.definition)||v(this.rule)||v(this.ruleset)||v(this.mixin.call)||v(this.comment)||v(this.directive))||v(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(b.charAt(g)!=="/")return;if(b.charAt(g+1)==="/")return new f.Comment(v(/^\/\/.*/),!0);if(a=v(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new f.Comment(a)},entities:{quoted:function(){var a,c=g,d;b.charAt(c)==="~"&&(c++,d=!0);if(b.charAt(c)!=='"'&&b.charAt(c)
!=="'")return;d&&v("~");if(a=v(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new f.Quoted(a[0],a[1]||a[2],d)},keyword:function(){var a;if(a=v(/^[_A-Za-z-][_A-Za-z0-9-]*/))return f.colors.hasOwnProperty(a)?new f.Color(f.colors[a].slice(1)):new f.Keyword(a)},call:function(){var a,b,c=g;if(!(a=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(l[h])))return;a=a[1].toLowerCase();if(a==="url")return null;g+=a.length;if(a==="alpha")return v(this.alpha);v("("),b=v(this.entities.arguments);if(!v(")"))return;if(a)return new f.Call(a,b,c)},arguments:function(){var a=[],b;while(b=v(this.entities.assignment)||v(this.expression)){a.push(b);if(!v(","))break}return a},literal:function(){return v(this.entities.dimension)||v(this.entities.color)||v(this.entities.quoted)},assignment:function(){var a,b;if((a=v(/^\w+(?=\s?=)/i))&&v("=")&&(b=v(this.entity)))return new f.Assignment(a,b)},u
rl:function(){var a;if(b.charAt(g)!=="u"||!v(/^url\(/))return;return a=v(this.entities.quoted)||v(this.entities.variable)||v(this.entities.dataURI)||v(/^[-\w%@$\/.&=:;#+?~]+/)||"",w(")"),new f.URL(a.value||a.data||a instanceof f.Variable?a:new f.Anonymous(a),r.paths)},dataURI:function(){var a;if(v(/^data:/)){a={},a.mime=v(/^[^\/]+\/[^,;)]+/)||"",a.charset=v(/^;\s*charset=[^,;)]+/)||"",a.base64=v(/^;\s*base64/)||"",a.data=v(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var a,c=g;if(b.charAt(g)==="@"&&(a=v(/^@@?[\w-]+/)))return new f.Variable(a,c)},color:function(){var a;if(b.charAt(g)==="#"&&(a=v(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new f.Color(a[1])},dimension:function(){var a,c=b.charCodeAt(g);if(c>57||c<45||c===47)return;if(a=v(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new f.Dimension(a[1],a[2])},javascript:function(){var
a,c=g,d;b.charAt(c)==="~"&&(c++,d=!0);if(b.charAt(c)!=="`")return;d&&v("~");if(a=v(/^`([^`]*)`/))return new f.JavaScript(a[1],g,d)}},variable:function(){var a;if(b.charAt(g)==="@"&&(a=v(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!y(/^[@\w.%-]+\/[@\w.-]+/))return;if((a=v(this.entity))&&v("/")&&(b=v(this.entity)))return new f.Shorthand(a,b)},mixin:{call:function(){var a=[],c,d,e,h=g,i=b.charAt(g),j=!1;if(i!=="."&&i!=="#")return;while(c=v(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))a.push(new f.Element(d,c,g)),d=v(">");v("(")&&(e=v(this.entities.arguments))&&v(")"),v(this.important)&&(j=!0);if(a.length>0&&(v(";")||y("}")))return new f.mixin.Call(a,e,h,j)},definition:function(){var a,c=[],d,e,h,i,j;if(b.charAt(g)!=="."&&b.charAt(g)!=
="#"||y(/^[^{]*(;|})/))return;s();if(d=v(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=d[1];while(h=v(this.entities.variable)||v(this.entities.literal)||v(this.entities.keyword)){h instanceof f.Variable?v(":")?(i=w(this.expression,"expected expression"),c.push({name:h.name,value:i})):c.push({name:h.name}):c.push({value:h});if(!v(","))break}w(")"),v(/^when/)&&(j=w(this.conditions,"expected condition")),e=v(this.block);if(e)return new f.mixin.Definition(a,c,e,j);t()}}},entity:function(){return v(this.entities.literal)||v(this.entities.variable)||v(this.entities.url)||v(this.entities.call)||v(this.entities.keyword)||v(this.entities.javascript)||v(this.comment)},end:function(){return v(";")||y("}")},alpha:function(){var a;if(!v(/^\(opacity=/i))return;if(a=v(/^\d+/)||v(this.entities.variable))return w(")"),new f.Alpha(a)},element:function(){var a,b,c,d;c=v(this.combinato
r),a=v(/^(?:\d+\.\d+|\d+)%/)||v(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||v("*")||v(this.attribute)||v(/^\([^)@]+\)/),a||v("(")&&(d=v(this.entities.variable))&&v(")")&&(a=new f.Paren(d));if(a)return new f.Element(c,a,g);if(c.value&&c.value.charAt(0)==="&")return new f.Element(c,null,g)},combinator:function(){var a,c=b.charAt(g);if(c===">"||c==="+"||c==="~"){g++;while(b.charAt(g)===" ")g++;return new f.Combinator(c)}if(c==="&"){a="&",g++,b.charAt(g)===" "&&(a="& ");while(b.charAt(g)===" ")g++;return new f.Combinator(a)}if(c===":"&&b.charAt(g+1)===":"){g+=2;while(b.charAt(g)===" ")g++;return new f.Combinator("::")}return b.charAt(g-1)===" "?new f.Combinator(" "):new f.Combinator(null)},selector:function(){var
a,c,d=[],e,h;while(c=v(this.element)){e=b.charAt(g),d.push(c);if(e==="{"||e==="}"||e===";"||e===",")break}if(d.length>0)return new f.Selector(d)},tag:function(){return v(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||v("*")},attribute:function(){var a="",b,c,d;if(!v("["))return;if(b=v(/^[a-zA-Z-]+/)||v(this.entities.quoted))(d=v(/^[|~*$^]?=/))&&(c=v(this.entities.quoted)||v(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!v("]"))return;if(a)return"["+a+"]"},block:function(){var a;if(v("{")&&(a=v(this.primary))&&v("}"))return a},ruleset:function(){var a=[],b,c,d;s();while(b=v(this.selector)){a.push(b),v(this.comment);if(!v(","))break;v(this.comment)}if(a.length>0&&(c=v(this.block)))return new f.Ruleset(a,c);k=g,t()},rule:function(){var a,c,d=b.charAt(g),e,i;s();if(d==="."||d==="#"||d==="&
")return;if(a=v(this.variable)||v(this.property)){a.charAt(0)!="@"&&(i=/^([^@+\/'"*`(;{}-]*);/.exec(l[h]))?(g+=i[0].length-1,c=new f.Anonymous(i[1])):a==="font"?c=v(this.font):c=v(this.value),e=v(this.important);if(c&&v(this.end))return new f.Rule(a,c,e,j);k=g,t()}},"import":function(){var a,b;if(v(/^@import\s+/)&&(a=v(this.entities.quoted)||v(this.entities.url))){b=v(this.mediaFeatures);if(v(";"))return new f.Import(a,r,b)}},mediaFeature:function(){var a=[];do if(e=v(this.entities.keyword))a.push(e);else if(v("(")){p=v(this.property),e=v(this.entity);if(!v(")"))return null;if(p&&e)a.push(new f.Paren(new f.Rule(p,e,null,g,!0)));else if(e)a.push(new f.Paren(e));else return null}while(e);if(a.length>0)return new f.Expression(a)},mediaFeatures:function(){var a,b=[];while(a=v(this.mediaFeature)){b.push(a);if(!v(","))break}return b.length>0?b:null},media:function(){var a;
if(v(/^@media/)){a=v(this.mediaFeatures);if(rules=v(this.block))return new f.Directive("@media",rules,a)}},directive:function(){var a,c,d,e,h,i;if(b.charAt(g)!=="@")return;if(c=v(this["import"])||v(this.media))return c;if(a=v(/^@page|@keyframes/)||v(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)){e=(v(/^[^{]+/)||"").trim();if(d=v(this.block))return new f.Directive(a+" "+e,d)}else if(a=v(/^@[-a-z]+/))if(a==="@font-face"){if(d=v(this.block))return new f.Directive(a,d)}else if((c=v(this.entity))&&v(";"))return new f.Directive(a,c)},font:function(){var a=[],b=[],c,d,e,g;while(g=v(this.shorthand)||v(this.entity))b.push(g);a.push(new f.Expression(b));if(v(","))while(g=v(this.expression)){a.push(g);if(!v(","))break}return new f.Value(a)},value:function(){var a,b=[],c;while(a=v(this.expression)){b.push(a);if(!v(","))break}if(b.length>0)return new f.Value(b)},important:function(){if(b.c
harAt(g)==="!")return v(/^! *important/)},sub:function(){var a;if(v("(")&&(a=v(this.expression))&&v(")"))return a},multiplication:function(){var a,b,c,d;if(a=v(this.operand)){while(!y(/^\/\*/)&&(c=v("/")||v("*"))&&(b=v(this.operand)))d=new f.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,c,d,e;if(a=v(this.multiplication)){while((d=v(/^[-+]\s+/)||b.charAt(g-1)!=" "&&(v("+")||v("-")))&&(c=v(this.multiplication)))e=new f.Operation(d,[e||a,c]);return e||a}},conditions:function(){var a,b,c=g,d;if(a=v(this.condition)){while(v(",")&&(b=v(this.condition)))d=new f.Condition("or",d||a,b,c);return d||a}},condition:function(){var a,b,c,d,e=g,h=!1;v(/^not/)&&(h=!0),w("(");if(a=v(this.addition)||v(this.entities.keyword)||v(this.entities.quoted))return(d=v(/^(?:>=|=<|[<=>])/))?(b=v(this.addition)||v(
this.entities.keyword)||v(this.entities.quoted))?c=new f.Condition(d,a,b,e,h):x("expected expression"):c=new f.Condition("=",a,new f.Keyword("true"),e,h),w(")"),v(/^and/)?new f.Condition("and",c,v(this.condition)):c},operand:function(){var a,c=b.charAt(g+1);b.charAt(g)==="-"&&(c==="@"||c==="(")&&(a=v("-"));var d=v(this.sub)||v(this.entities.dimension)||v(this.entities.color)||v(this.entities.variable)||v(this.entities.call);return a?new f.Operation("*",[new f.Dimension(-1),d]):d},expression:function(){var a,b,c=[],d;while(a=v(this.addition)||v(this.entity))c.push(a);if(c.length>0)return new f.Expression(c)},property:function(){var a;if(a=v(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}};if(d.mode==="browser"||d.mode==="rhino")d.Parser.importer=function(a,b,c,d){a.charAt(0)!=="/"&&b.length>0&&(a=b[0]+a),o({href:a,title:a,ty
pe:d.mime},c,!0)};(function(a){function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function d(a){return Math.min(1,Math.max(0,a))}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){return a=a<0?a+1:a>1?a-1:a,a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(Math.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%"
;)},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();return e.s+=c.value/100,e.s=d(e.s),b(e)},desaturate:function(a,c){var e=a.toHSL();return e.s-=c.value/100,e.s=d(e.s),b(e)},lighten:function(a,c){var e=a.toHSL();return e.l+=c.value/100,e.l=d(e.l),b(e)},darken:function(a,c){var e=a.toHSL();return e.l-=c.value/100,e.l=d(e.l),b(e)},fadein:function(a,c){var e=a.toHSL();return e.a+=c.value/100,e.a=d(e.a),b(e)},fadeout:function(a,c){var e=a.toHSL();return e.a-=c.value/100,e.a=d(e.a),b(e)},fade:function(a,c){var e=a.toHSL();return e.a=c.value/100,e.a=d(e.a),b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;return d.h=e<0?360+e:e,b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);ret
urn new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e<c.length;e++)d=d.replace(/%[sda]/i,function(a){var b=a.match(/s/i)?c[e].value:c[e].toCSS();return a.match(/[A-Z]$/)?encodeURIComponent(b):b});return d=d.replace(/%%/g,"%"),new a.Quoted('"'+d+'"',d)},round:function(a){return this._math("round",a)},ceil:function(a){return this._math("ceil",a)},floor:function(a){return this._math("floor",a)},_math:function(b,d){if(d instanceof a.Dimension)return new a.Dimension(Math[b](c(d)),d.unit
);if(typeof d=="number")return Math[b](d);throw{type:"Argument",message:"argument must be a number"}},argb:function(b){return new a.Anonymous(b.toARGB())},percentage:function(b){return new a.Dimension(b.value*100,"%")},color:function(b){if(b instanceof a.Quoted)return new a.Color(b.value.slice(1));throw{type:"Argument",message:"argument must be a string"}},iscolor:function(b){return this._isa(b,a.Color)},isnumber:function(b){return this._isa(b,a.Dimension)},isstring:function(b){return this._isa(b,a.Quoted)},iskeyword:function(b){return this._isa(b,a.Keyword)},isurl:function(b){return this._isa(b,a.URL)},ispixel:function(b){return b instanceof a.Dimension&&b.unit==="px"?a.True:a.False},ispercentage:function(b){return b instanceof a.Dimension&&b.unit==="%"?a.True:a.False},isem:function(b){return b instanceof a.Dimension&&b.unit==="em"?a.True:a.False},_isa:function(b,c){ret
urn b instanceof c?a.True:a.False}}})(c("./tree")),function(a){a.colors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",d
arkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"
;#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred
:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87
ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"}}(c("./tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(a){return this.value.eval&&(this.value=this.value.eval(a)),this}}}(c("../tree")),function(a){a.Anonymous=function(a){this.value=a.value||a},a.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this}}}(c("../tree")),function(a){a.As
signment=function(a,b){this.key=a,this.value=b},a.Assignment.prototype={toCSS:function(){return this.key+"="+(this.value.toCSS?this.value.toCSS():this.value)},eval:function(a){return this.value.eval&&(this.value=this.value.eval(a)),this}}}(c("../tree")),function(a){a.Call=function(a,b,c){this.name=a,this.args=b,this.index=c},a.Call.prototype={eval:function(b){var c=this.args.map(function(a){return a.eval(b)});if(!(this.name in a.functions))return new a.Anonymous(this.name+"("+c.map(function(a){return a.toCSS()}).join(", ")+")");try{return a.functions[this.name].apply(a.functions,c)}catch(d){throw{type:d.type||"Runtime",message:"error evaluating function `"+this.name+"`"+(d.message?": "+d.message:""),index:this.index}}},toCSS:function(a){return this.eval(a).toCSS()}}}(c("../tree")),function(a){a.Color=function(a,b){Array.isArray(a)?this.rgb=a:a.length==6?this.rgb=a.ma
tch(/.{2}/g).map(function(a){return parseInt(a,16)}):this.rgb=a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha=typeof b=="number"?b:1},a.Color.prototype={eval:function(){return this},toCSS:function(){return this.alpha<1?"rgba("+this.rgb.map(function(a){return Math.round(a)}).concat(this.alpha).join(", ")+")":"#"+this.rgb.map(function(a){return a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);switch(e){case a:g=(b-c)/j+(b<c?6:0);break;case b:g=(c-a)/j+2;break;case c:g=(a-b)/j+4}g/=6}re
turn{h:g*360,s:h,l:i,a:d}},toARGB:function(){var a=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+a.map(function(a){return a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")}}}(c("../tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Condition=function(a,b,c,d,e){this.op=a.trim(),this.lvalue=b,this.rvalue=c,this.index=d,this.negate=e},a.Condition.prototype.eval=function(a){var b=this.lvalue.eval(a),c=this.rvalue.eval(a),d=this.index,e,e=function(a){switch(a){case"and":return b&&c;case"or":return b||c;default:if(b.compare)e=b.compare(c);else if(c.compare)e=c.compare(b);else throw{type:"Type",message:"Unable to perform comparison",index:d};switch(e){case-1:return a==="<&quo
t;||a==="=<";case 0:return a==="="||a===">="||a==="=<";case 1:return a===">"||a===">="}}}(this.op);return this.negate?!e:e}}(c("../tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)},compare:function(b){return b instanceof a.Dimension?b.value>this.value?-1:b.value<this.value?1:0:-1}}}(c("../tree")),function(a){a.Directive=function(b,c,d){this.name=b,this.features=d&&new a.Value(d),Array.isArray(c)?(this.ruleset=new a.Ruleset([],c),this.ruleset.allowImports=!0):this.value=c},a.Directive.prototype={toCSS:function(a,b){var c=this.features?" "+this.features.to
CSS(b):"";return this.ruleset?(this.ruleset.root=!0,this.name+c+(b.compress?"{":" {\n ")+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n ")+(b.compress?"}":"\n}\n")):this.name+" "+this.value.toCSS()+";\n"},eval:function(a){return this.features=this.features&&this.features.eval(a),a.frames.unshift(this),this.ruleset=this.ruleset&&this.ruleset.eval(a),a.frames.shift(),this},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(c("../tree")),function(a){a.Element=function(b,c,d){this.combinator=b instanceof a.Combinator?b:new a.Combinator(b),typeof c=="string"?this.value=c.trim():c?this.value=c:this.value="",this.index=d},a.Element.prototype.eval=function(b){return new a.Element(
this.combinator,this.value.eval?this.value.eval(b):this.value,this.index)},a.Element.prototype.toCSS=function(a){return this.combinator.toCSS(a||{})+(this.value.toCSS?this.value.toCSS(a):this.value)},a.Combinator=function(a){a===" "?this.value=" ":a==="& "?this.value="& ":this.value=a?a.trim():""},a.Combinator.prototype.toCSS=function(a){return{"":""," ":" ","&":"","& ":" ",":":" :","::":"::","+":a.compress?"+":" + ","~":a.compress?"~":" ~ ",">":a.compress?">":" > "}[this.value]}}(c("../tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.lengt
h===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS?b.toCSS(a):""}).join(" ")}}}(c("../tree")),function(a){a.Import=function(b,c,d){var e=this;this._path=b,this.features=d&&new a.Value(d),b instanceof a.Quoted?this.path=/\.(le?|c)ss(\?.*)?$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value||b.value,this.css=/css(\?.*)?$/.test(this.path),this.css||c.push(this.path,function(a,b){e.root=b})},a.Import.prototype={toCSS:function(a){var b=this.features?" "+this.features.toCSS(a):"";return this.css?"@import "+this._path.toCSS()+b+";\n":""},eval:function(b){var c,d=this.features&&this.features.eval(b);if(this.css)return this;c=new a.Ruleset([],this.root.rules.slice(0));for(var e=0;e<c.rules.length;e++)c.rules[e]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[e,1].concat(c.rules[e].eval(b)));return this.fe
atures?new a.Directive("@media",c.rules,this.features.value):c.rules}}}(c("../tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify((new a.Variable("@"+e,d.index)).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: `"+f+"`",index:this.index}}for(var h in b.frames[0].variables())e[h.slice(1)]={value:b.frames[0].variables()[h].value,toJS:function(){return this.value.eval(b).toCSS()}};try{c=f.call(e)}catch(g){throw{message:"JavaScript evaluation error: '"+
+g.name+": "+g.message+"'",index:this.index}}return typeof c=="string"?new a.Quoted('"'+c+'"',c,this.escaped,this.index):Array.isArray(c)?new a.Anonymous(c.join(", ")):new a.Anonymous(c)}}}(c("../tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value},compare:function(b){return b instanceof a.Keyword?b.value===this.value?0:1:-1}},a.True=new a.Keyword("true"),a.False=new a.Keyword("false")}(c("../tree")),function(a){a.mixin={},a.mixin.Call=function(b,c,d,e){this.selector=new a.Selector(b),this.arguments=c,this.index=d,this.important=e},a.mixin.Call.prototype={eval:function(a){var b,c,d=[],e=!1;for(var f=0;f<a.frames.length;f++)if((b=a.frames[f].find(this.selector)).length>0){c=this.arguments&&this.arguments.map(function(b){return b.eval(a)});for(var g=0;g<b.length;g++)if(b[g].match(c,a))try{Arra
y.prototype.push.apply(d,b[g].eval(a,this.arguments,this.important).rules),e=!0}catch(h){throw{message:h.message,index:h.index,stack:h.stack,call:this.index}}if(e)return d;throw{type:"Runtime",message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(a){return a.toCSS()}).join(", ")+")`",index:this.index}}throw{type:"Name",message:this.selector.toCSS().trim()+" is undefined",index:this.index}}},a.mixin.Definition=function(b,c,d,e){this.name=b,this.selectors=[new a.Selector([new a.Element(null,b)])],this.params=c,this.condition=e,this.arity=c.length,this.rules=d,this._lookups={},this.required=c.reduce(function(a,b){return!b.name||b.name&&!b.value?a+1:a},0),this.parent=a.Ruleset.prototype,this.frames=[]},a.mixin.Definition.prototype={toCSS:function(){return""},variable:function(a){return this.parent.variable.call(this,a)},variables:function(){retu
rn this.parent.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},evalParams:function(b,c){var d=new a.Ruleset(null,[]);for(var e=0,f;e<this.params.length;e++)if(this.params[e].name)if(f=c&&c[e]||this.params[e].value)d.rules.unshift(new a.Rule(this.params[e].name,f.eval(b)));else throw{type:"Runtime",message:"wrong number of arguments for "+this.name+" ("+c.length+" for "+this.arity+")"};return d},eval:function(b,c,d){var e=this.evalParams(b,c),f,g=[],h;for(var i=0;i<Math.max(this.params.length,c&&c.length);i++)g.push(c[i]||this.params[i].value);return e.rules.unshift(new a.Rule("@arguments",(new a.Expression(g)).eval(b))),h=d?this.rules.map(function(b){return new a.Rule(b.name,b.value,"!important",b.index)}):this.rules.slice(0),(new a.Ruleset(null,h)).eval({frames:[this,e].concat(this.frames,b.fram
es)})},match:function(a,b){var c=a&&a.length||0,d,e;if(c<this.required)return!1;if(this.required>0&&c>this.params.length)return!1;if(this.condition&&!this.condition.eval({frames:[this.evalParams(b,a)].concat(b.frames)}))return!1;d=Math.min(c,this.arity);for(var f=0;f<d;f++)if(!this.params[f].name&&a[f].eval(b).toCSS()!=this.params[f].value.eval(b).toCSS())return!1;return!0}}}(c("../tree")),function(a){a.Operation=function(a,b){this.op=a.trim(),this.operands=b},a.Operation.prototype.eval=function(b){var c=this.operands[0].eval(b),d=this.operands[1].eval(b),e;if(c instanceof a.Dimension&&d instanceof a.Color)if(this.op==="*"||this.op==="+")e=d,d=c,c=e;else throw{name:"OperationError",message:"Can't substract or divide a color from a number"};return c.operate(this.op,d)},a.operate=function(a,b,c){switch(a){case"+":return b+c;case"-":return b-c;case"*":retu
rn b*c;case"/":return b/c}}}(c("../tree")),function(a){a.Paren=function(a){this.value=a},a.Paren.prototype={toCSS:function(a){return"("+this.value.toCSS(a)+")"},eval:function(b){return new a.Paren(this.value.eval(b))}}}(c("../tree")),function(a){a.Quoted=function(a,b,c,d){this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d},a.Quoted.prototype={toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(b){var c=this,d=this.value.replace(/`([^`]+)`/g,function(d,e){return(new a.JavaScript(e,c.index,!0)).eval(b).value}).replace(/@\{([\w-]+)\}/g,function(d,e){var f=(new a.Variable("@"+e,c.index)).eval(b);return"value"in f?f.value:f.toCSS()});return new a.Quoted(this.quote+d+this.quote,d,this.escaped,this.index)}}}(c("../tree")),function(a){a.Rule=function(b,c,d,e,f){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?&q
uot; "+d.trim():"",this.index=e,this.inline=f||!1,b.charAt(0)==="@"?this.variable=!0:this.variable=!1},a.Rule.prototype.toCSS=function(a){return this.variable?"":this.name+(a.compress?":":": ")+this.value.toCSS(a)+this.important+(this.inline?"":";")},a.Rule.prototype.eval=function(b){return new a.Rule(this.name,this.value.eval(b),this.important,this.index,this.inline)},a.Shorthand=function(a,b){this.a=a,this.b=b},a.Shorthand.prototype={toCSS:function(a){return this.a.toCSS(a)+"/"+this.b.toCSS(a)},eval:function(){return this}}}(c("../tree")),function(a){a.Ruleset=function(a,b){this.selectors=a,this.rules=b,this._lookups={}},a.Ruleset.prototype={eval:function(b){var c=this.selectors&&this.selectors.map(function(a){return a.eval(b)}),d=new a.Ruleset(c,this.rules.slice(0));d.root=this.root,d.allowImports=this.allowImports,b.frames.unshift(d);if(d.root||d.allowImports)for(var e=0;e<d
.rules.length;e++)d.rules[e]instanceof a.Import&&Array.prototype.splice.apply(d.rules,[e,1].concat(d.rules[e].eval(b)));for(var e=0;e<d.rules.length;e++)d.rules[e]instanceof a.mixin.Definition&&(d.rules[e].frames=b.frames.slice(0));for(var e=0;e<d.rules.length;e++)d.rules[e]instanceof a.mixin.Call&&Array.prototype.splice.apply(d.rules,[e,1].concat(d.rules[e].eval(b)));for(var e=0,f;e<d.rules.length;e++)f=d.rules[e],f instanceof a.mixin.Definition||(d.rules[e]=f.eval?f.eval(b):f);return b.frames.shift(),d},match:function(a){return!a||a.length===0},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(b,c){return c instanceof a.Rule&&c.variable===!0&&(b[c.name]=c),b},{})},variable:function(a){return this.variables()[a]},rulesets:function(){return this._rulesets?this._rulesets:this._rulesets=this.rules.filter(function(b){return b instanceof a.Ruleset||b instanceof a.mixin.Definition})},fin
d:function(b,c){c=c||this;var d=[],e,f,g=b.toCSS();return g in this._lookups?this._lookups[g]:(this.rulesets().forEach(function(e){if(e!==c)for(var g=0;g<e.selectors.length;g++)if(f=b.match(e.selectors[g])){b.elements.length>e.selectors[g].elements.length?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}}),this._lookups[g]=d)},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;this.root||(b.length===0?g=this.selectors.map(function(a){return[a]}):this.joinSelectors(g,b,this.selectors));for(var j=0;j<this.rules.length;j++)i=this.rules[j],i.rules||i instanceof a.Directive?f.push(i.toCSS(g,c)):i instanceof a.Comment?i.silent||(this.root?f.push(i.toCSS(c)):e.push(i.toCSS(c))):i.toCSS&&!i.variable?e.push(i.toCSS(c)):i.value&&!i.variable&&e.push(i.value.toString());return f=f.join(""),this.root?d.push(e.join(c.compress?"":"\n")):e.length>0&&(h=g.map(function(a){return a.map(fun
ction(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":g.length>3?",\n":", "),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f),d.join("")+(c.compress?"\n":"")},joinSelectors:function(a,b,c){for(var d=0;d<c.length;d++)this.joinSelector(a,b,c[d])},joinSelector:function(b,c,d){var e=[],f=[],g=[],h=[],i=!1,j;for(var k=0;k<d.elements.length;k++)j=d.elements[k],j.combinator.value.charAt(0)==="&"&&(i=!0),i?h.push(j):g.push(j);i||(h=g,g=[]),g.length>0&&e.push(new a.Selector(g)),h.length>0&&f.push(new a.Selector(h));for(var l=0;l<c.length;l++)b.push(e.concat(c[l]).concat(f))}}}(c("../tree")),function(a){a.Selector=function(a){this.elements=a,this.elements[0].combinator.value===""&&(this.elements[0].combinator.value=&qu
ot; ")},a.Selector.prototype.match=function(a){var b=this.elements.length,c=a.elements.length,d=Math.min(b,c);if(b<c)return!1;for(var e=0;e<d;e++)if(this.elements[e].value!==a.elements[e].value)return!1;return!0},a.Selector.prototype.eval=function(b){return new a.Selector(this.elements.map(function(a){return a.eval(b)}))},a.Selector.prototype.toCSS=function(a){return this._css?this._css:this._css=this.elements.map(function(b){return typeof b=="string"?" "+b.trim():b.toCSS(a)}).join("")}}(c("../tree")),function(b){b.URL=function(b,c){b.data?this.attrs=b:(typeof a!="undefined"&&!/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(b.value)&&c.length>0&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:
this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("../tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("../tree")),function(a){a.Variable=function(a,b){this.name=a,this.index=b},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{message:"variable "+e+" is undefined",index:this.index}}}}(c("../tree")),function(a){a.find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.ca
ll(a,a[c]))return d;return null},a.jsify=function(a){return Array.isArray(a.value)&&a.value.length>1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)}}(c("./tree"));var g=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||g?"development":"production"),d.async=!1,d.poll=d.poll||(g?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&n(function(a,b,c){a&&r(a.toCSS(),b,c.lastModified)})},d.poll)):d.o
ptimization=3;var h;try{h=typeof a.localStorage=="undefined"?null:a.localStorage}catch(i){h=null}var j=document.getElementsByTagName("link"),k=/^text\/(x-)?less$/;d.sheets=[];for(var l=0;l<j.length;l++)(j[l].rel==="stylesheet/less"||j[l].rel.match(/stylesheet/)&&j[l].type.match(k))&&d.sheets.push(j[l]);d.refresh=function(a){var b,c;b=c=new Date,n(function(a,d,e){e.local?v("loading "+d.href+" from cache."):(v("parsed "+d.href+" successfully."),r(a.toCSS(),d,e.lastModified)),v("css for "+d.href+" generated in "+(new Date-c)+"ms"),e.remaining===0&&v("css generated in "+(new Date-b)+"ms"),c=new Date},a),m()},d.refreshStyles=m,d.refresh(d.env==="development")})(window);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless121js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.1.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.1.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.1.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3318 @@
</span><ins>+//
+// LESS - Leaner CSS v1.2.1
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+ // Rhino
+ // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+ if (typeof(window) === 'undefined') { less = {} }
+ else { less = window.less = {} }
+ tree = less.tree = {};
+ less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+ // Node.js
+ less = exports,
+ tree = require('./tree');
+ less.mode = 'node';
+} else {
+ // Browser
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+ less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ contents: {}, // Holds the imported file contents
+ mime: env && env.mime, // MIME type of .less files
+ error: null, // Error in parsing/evaluating an import
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (e, root, contents) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+ that.contents[path] = contents;
+
+ if (e && !that.error) { that.error = e }
+ callback(e, root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ function expect(arg, msg) {
+ var result = $(arg);
+ if (! result) {
+ error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+ : "unexpected token"));
+ } else {
+ return result;
+ }
+ }
+
+ function error(msg, type) {
+ throw { index: i, type: type || 'Syntax', message: msg };
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ function getInput(e, env) {
+ if (e.filename && env.filename && (e.filename !== env.filename)) {
+ return parser.imports.contents[e.filename];
+ } else {
+ return input;
+ }
+ }
+
+ function getLocation(index, input) {
+ for (var n = index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ return { line: typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+ column: column };
+ }
+
+ function LessError(e, env) {
+ var input = getInput(e, env),
+ loc = getLocation(e.index, input),
+ line = loc.line,
+ col = loc.column,
+ lines = input.split('\n');
+
+ this.type = e.type || 'Syntax';
+ this.message = e.message;
+ this.filename = e.filename || env.filename;
+ this.index = e.index;
+ this.line = typeof(line) === 'number' ? line + 1 : null;
+ this.callLine = e.call && (getLocation(e.call, input) + 1);
+ this.callExtract = lines[getLocation(e.call, input)];
+ this.stack = e.stack;
+ this.column = col;
+ this.extract = [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ];
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ chunks = [];
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam,
+ inString;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = i;
+
+ if (!inString && !inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ if (c === '{' && !inString && !inParam) { level ++;
+ chunk.push(c);
+ } else if (c === '}' && !inString && !inParam) { level --;
+ chunk.push(c);
+ chunks[++j] = chunk = [];
+ } else if (c === '(' && !inString && !inParam) {
+ chunk.push(c);
+ inParam = true;
+ } else if (c === ')' && !inString && inParam) {
+ chunk.push(c);
+ inParam = false;
+ } else {
+ if (c === '"' || c === "'" || c === '`') {
+ if (! inString) {
+ inString = c;
+ } else {
+ inString = inString === c ? false : inString;
+ }
+ }
+ chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ throw {
+ type: 'Syntax',
+ message: "Missing closing `}`",
+ filename: env.filename
+ };
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ try {
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+ } catch (e) {
+ return callback(new(LessError)(e, env));
+ }
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [], importError;
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ throw new(LessError)(e, env);
+ }
+
+ if ((importError = parser.imports.error)) { // Check if there was an error during importing
+ if (importError instanceof LessError) throw importError;
+ else throw new(LessError)(importError, env);
+ }
+
+ if (options.yuicompress && less.mode === 'node') {
+ return require('./cssmin').compressor.cssmin(css);
+ } else if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ type: "Parse",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+
+ if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+ if (tree.colors.hasOwnProperty(k)) {
+ // detect named color
+ return new(tree.Color)(tree.colors[k].slice(1));
+ } else {
+ return new(tree.Keyword)(k);
+ }
+ }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args, index = i;
+
+ if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args, index, env.filename) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.entities.assignment) || $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ // Assignments are argument entities for calls.
+ // They are present in ie filter properties as shown below.
+ //
+ // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+ //
+
+ assignment: function () {
+ var key, value;
+ if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+ return new(tree.Assignment)(key, value);
+ }
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+
+ expect(')');
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index, env.filename);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i), important = false;
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e, i));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if ($(this.important)) {
+ important = true;
+ }
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value, cond;
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ save();
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ while (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ value = expect(this.expression, 'expected expression');
+ params.push({ name: param.name, value: value });
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ if (! $(',')) { break }
+ }
+ expect(')');
+
+ if ($(/^when/)) { // Guard
+ cond = expect(this.conditions, 'expected condition');
+ }
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset, cond);
+ } else {
+ restore();
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^\(opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ expect(')');
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c, v;
+
+ c = $(this.combinator);
+ e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+ $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+ if (! e) {
+ $('(') && (v = $(this.entities.variable)) && $(')') && (e = new(tree.Paren)(v));
+ }
+
+ if (e) { return new(tree.Element)(c, e, i) }
+
+ if (c.value && c.value.charAt(0) === '&') {
+ return new(tree.Element)(c, null, i);
+ }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === '&') {
+ match = '&';
+ i++;
+ if(input.charAt(i) === ' ') {
+ match = '& ';
+ }
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(match);
+ } else if (c === ':' && input.charAt(i + 1) === ':') {
+ i += 2;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)('::');
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path, features, index = i;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url))) {
+ features = $(this.mediaFeatures);
+ if ($(';')) {
+ return new(tree.Import)(path, imports, features, index);
+ }
+ }
+ },
+
+ mediaFeature: function () {
+ var nodes = [];
+
+ do {
+ if (e = $(this.entities.keyword)) {
+ nodes.push(e);
+ } else if ($('(')) {
+ p = $(this.property);
+ e = $(this.entity);
+ if ($(')')) {
+ if (p && e) {
+ nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+ } else if (e) {
+ nodes.push(new(tree.Paren)(e));
+ } else {
+ return null;
+ }
+ } else { return null }
+ }
+ } while (e);
+
+ if (nodes.length > 0) {
+ return new(tree.Expression)(nodes);
+ }
+ },
+
+ mediaFeatures: function () {
+ var f, features = [];
+ while (f = $(this.mediaFeature)) {
+ features.push(f);
+ if (! $(',')) { break }
+ }
+ return features.length > 0 ? features : null;
+ },
+
+ media: function () {
+ var features;
+
+ if ($(/^@media/)) {
+ features = $(this.mediaFeatures);
+
+ if (rules = $(this.block)) {
+ return new(tree.Directive)('@media', rules, features);
+ }
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types, e, nodes;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import']) || $(this.media)) {
+ return value;
+ } else if (name = $(/^@page|@keyframes/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ conditions: function () {
+ var a, b, index = i, condition;
+
+ if (a = $(this.condition)) {
+ while ($(',') && (b = $(this.condition))) {
+ condition = new(tree.Condition)('or', condition || a, b, index);
+ }
+ return condition || a;
+ }
+ },
+ condition: function () {
+ var a, b, c, op, index = i, negate = false;
+
+ if ($(/^not/)) { negate = true }
+ expect('(');
+ if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+ if (op = $(/^(?:>=|=<|[<=>])/)) {
+ if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+ c = new(tree.Condition)(op, a, b, index, negate);
+ } else {
+ error('expected expression');
+ }
+ } else {
+ c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+ }
+ expect(')');
+ return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (path.charAt(0) !== '/' && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fade: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a = amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ return this._math('round', n);
+ },
+ ceil: function (n) {
+ return this._math('ceil', n);
+ },
+ floor: function (n) {
+ return this._math('floor', n);
+ },
+ _math: function (fn, n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math[fn](n);
+ } else {
+ throw { type: "Argument", message: "argument must be a number" };
+ }
+ },
+ argb: function (color) {
+ return new(tree.Anonymous)(color.toARGB());
+
+ },
+ percentage: function (n) {
+ return new(tree.Dimension)(n.value * 100, '%');
+ },
+ color: function (n) {
+ if (n instanceof tree.Quoted) {
+ return new(tree.Color)(n.value.slice(1));
+ } else {
+ throw { type: "Argument", message: "argument must be a string" };
+ }
+ },
+ iscolor: function (n) {
+ return this._isa(n, tree.Color);
+ },
+ isnumber: function (n) {
+ return this._isa(n, tree.Dimension);
+ },
+ isstring: function (n) {
+ return this._isa(n, tree.Quoted);
+ },
+ iskeyword: function (n) {
+ return this._isa(n, tree.Keyword);
+ },
+ isurl: function (n) {
+ return this._isa(n, tree.URL);
+ },
+ ispixel: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+ },
+ ispercentage: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+ },
+ isem: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+ },
+ _isa: function (n, Type) {
+ return (n instanceof Type) ? tree.True : tree.False;
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+ tree.colors = {
+ 'aliceblue':'#f0f8ff',
+ 'antiquewhite':'#faebd7',
+ 'aqua':'#00ffff',
+ 'aquamarine':'#7fffd4',
+ 'azure':'#f0ffff',
+ 'beige':'#f5f5dc',
+ 'bisque':'#ffe4c4',
+ 'black':'#000000',
+ 'blanchedalmond':'#ffebcd',
+ 'blue':'#0000ff',
+ 'blueviolet':'#8a2be2',
+ 'brown':'#a52a2a',
+ 'burlywood':'#deb887',
+ 'cadetblue':'#5f9ea0',
+ 'chartreuse':'#7fff00',
+ 'chocolate':'#d2691e',
+ 'coral':'#ff7f50',
+ 'cornflowerblue':'#6495ed',
+ 'cornsilk':'#fff8dc',
+ 'crimson':'#dc143c',
+ 'cyan':'#00ffff',
+ 'darkblue':'#00008b',
+ 'darkcyan':'#008b8b',
+ 'darkgoldenrod':'#b8860b',
+ 'darkgray':'#a9a9a9',
+ 'darkgrey':'#a9a9a9',
+ 'darkgreen':'#006400',
+ 'darkkhaki':'#bdb76b',
+ 'darkmagenta':'#8b008b',
+ 'darkolivegreen':'#556b2f',
+ 'darkorange':'#ff8c00',
+ 'darkorchid':'#9932cc',
+ 'darkred':'#8b0000',
+ 'darksalmon':'#e9967a',
+ 'darkseagreen':'#8fbc8f',
+ 'darkslateblue':'#483d8b',
+ 'darkslategray':'#2f4f4f',
+ 'darkslategrey':'#2f4f4f',
+ 'darkturquoise':'#00ced1',
+ 'darkviolet':'#9400d3',
+ 'deeppink':'#ff1493',
+ 'deepskyblue':'#00bfff',
+ 'dimgray':'#696969',
+ 'dimgrey':'#696969',
+ 'dodgerblue':'#1e90ff',
+ 'firebrick':'#b22222',
+ 'floralwhite':'#fffaf0',
+ 'forestgreen':'#228b22',
+ 'fuchsia':'#ff00ff',
+ 'gainsboro':'#dcdcdc',
+ 'ghostwhite':'#f8f8ff',
+ 'gold':'#ffd700',
+ 'goldenrod':'#daa520',
+ 'gray':'#808080',
+ 'grey':'#808080',
+ 'green':'#008000',
+ 'greenyellow':'#adff2f',
+ 'honeydew':'#f0fff0',
+ 'hotpink':'#ff69b4',
+ 'indianred':'#cd5c5c',
+ 'indigo':'#4b0082',
+ 'ivory':'#fffff0',
+ 'khaki':'#f0e68c',
+ 'lavender':'#e6e6fa',
+ 'lavenderblush':'#fff0f5',
+ 'lawngreen':'#7cfc00',
+ 'lemonchiffon':'#fffacd',
+ 'lightblue':'#add8e6',
+ 'lightcoral':'#f08080',
+ 'lightcyan':'#e0ffff',
+ 'lightgoldenrodyellow':'#fafad2',
+ 'lightgray':'#d3d3d3',
+ 'lightgrey':'#d3d3d3',
+ 'lightgreen':'#90ee90',
+ 'lightpink':'#ffb6c1',
+ 'lightsalmon':'#ffa07a',
+ 'lightseagreen':'#20b2aa',
+ 'lightskyblue':'#87cefa',
+ 'lightslategray':'#778899',
+ 'lightslategrey':'#778899',
+ 'lightsteelblue':'#b0c4de',
+ 'lightyellow':'#ffffe0',
+ 'lime':'#00ff00',
+ 'limegreen':'#32cd32',
+ 'linen':'#faf0e6',
+ 'magenta':'#ff00ff',
+ 'maroon':'#800000',
+ 'mediumaquamarine':'#66cdaa',
+ 'mediumblue':'#0000cd',
+ 'mediumorchid':'#ba55d3',
+ 'mediumpurple':'#9370d8',
+ 'mediumseagreen':'#3cb371',
+ 'mediumslateblue':'#7b68ee',
+ 'mediumspringgreen':'#00fa9a',
+ 'mediumturquoise':'#48d1cc',
+ 'mediumvioletred':'#c71585',
+ 'midnightblue':'#191970',
+ 'mintcream':'#f5fffa',
+ 'mistyrose':'#ffe4e1',
+ 'moccasin':'#ffe4b5',
+ 'navajowhite':'#ffdead',
+ 'navy':'#000080',
+ 'oldlace':'#fdf5e6',
+ 'olive':'#808000',
+ 'olivedrab':'#6b8e23',
+ 'orange':'#ffa500',
+ 'orangered':'#ff4500',
+ 'orchid':'#da70d6',
+ 'palegoldenrod':'#eee8aa',
+ 'palegreen':'#98fb98',
+ 'paleturquoise':'#afeeee',
+ 'palevioletred':'#d87093',
+ 'papayawhip':'#ffefd5',
+ 'peachpuff':'#ffdab9',
+ 'peru':'#cd853f',
+ 'pink':'#ffc0cb',
+ 'plum':'#dda0dd',
+ 'powderblue':'#b0e0e6',
+ 'purple':'#800080',
+ 'red':'#ff0000',
+ 'rosybrown':'#bc8f8f',
+ 'royalblue':'#4169e1',
+ 'saddlebrown':'#8b4513',
+ 'salmon':'#fa8072',
+ 'sandybrown':'#f4a460',
+ 'seagreen':'#2e8b57',
+ 'seashell':'#fff5ee',
+ 'sienna':'#a0522d',
+ 'silver':'#c0c0c0',
+ 'skyblue':'#87ceeb',
+ 'slateblue':'#6a5acd',
+ 'slategray':'#708090',
+ 'slategrey':'#708090',
+ 'snow':'#fffafa',
+ 'springgreen':'#00ff7f',
+ 'steelblue':'#4682b4',
+ 'tan':'#d2b48c',
+ 'teal':'#008080',
+ 'thistle':'#d8bfd8',
+ 'tomato':'#ff6347',
+ 'turquoise':'#40e0d0',
+ 'violet':'#ee82ee',
+ 'wheat':'#f5deb3',
+ 'white':'#ffffff',
+ 'whitesmoke':'#f5f5f5',
+ 'yellow':'#ffff00',
+ 'yellowgreen':'#9acd32'
+ };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+ this.key = key;
+ this.value = val;
+};
+tree.Assignment.prototype = {
+ toCSS: function () {
+ return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+ this.name = name;
+ this.args = args;
+ this.index = index;
+ this.filename = filename;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ try {
+ return tree.functions[this.name].apply(tree.functions, args);
+ } catch (e) {
+ throw { type: e.type || "Runtime",
+ message: "error evaluating function `" + this.name + "`" +
+ (e.message ? ': ' + e.message : ''),
+ index: this.index, filename: this.filename };
+ }
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ },
+ toARGB: function () {
+ var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+ return '#' + argb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+ this.op = op.trim();
+ this.lvalue = l;
+ this.rvalue = r;
+ this.index = i;
+ this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+ var a = this.lvalue.eval(env),
+ b = this.rvalue.eval(env);
+
+ var i = this.index, result
+
+ var result = (function (op) {
+ switch (op) {
+ case 'and':
+ return a && b;
+ case 'or':
+ return a || b;
+ default:
+ if (a.compare) {
+ result = a.compare(b);
+ } else if (b.compare) {
+ result = b.compare(a);
+ } else {
+ throw { type: "Type",
+ message: "Unable to perform comparison",
+ index: i };
+ }
+ switch (result) {
+ case -1: return op === '<' || op === '=<';
+ case 0: return op === '=' || op === '>=' || op === '=<';
+ case 1: return op === '>' || op === '>=';
+ }
+ }
+ })(this.op);
+ return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ },
+
+ // TODO: Perform unit conversion before comparing
+ compare: function (other) {
+ if (other instanceof tree.Dimension) {
+ if (other.value > this.value) {
+ return -1;
+ } else if (other.value < this.value) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ return -1;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value, features) {
+ this.name = name;
+ this.features = features && new(tree.Value)(features);
+
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ this.ruleset.allowImports = true;
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + features + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ this.features = this.features && this.features.eval(env);
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+
+ if (typeof(value) === 'string') {
+ this.value = value.trim();
+ } else if (value) {
+ this.value = value;
+ } else {
+ this.value = "";
+ }
+ this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+ return new(tree.Element)(this.combinator,
+ this.value.eval ? this.value.eval(env) : this.value,
+ this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + (this.value.toCSS ? this.value.toCSS(env) : this.value);
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else if (value === '& ') {
+ this.value = '& ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ '& ' : ' ',
+ ':' : ' :',
+ '::': '::',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS ? e.toCSS(env) : '';
+ }).join(' ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, index) {
+ var that = this;
+
+ this.index = index;
+ this._path = path;
+ this.features = features && new(tree.Value)(features);
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css(\?.*)?$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (e, root) {
+ if (e) { e.index = index }
+ that.root = root || new(tree.Ruleset)([], []);
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function (env) {
+ var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+ if (this.css) {
+ return "@import " + this._path.toCSS() + features + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset, features = this.features && this.features.eval(env);
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return this.features ? new(tree.Directive)('@media', ruleset.rules, this.features.value) : ruleset.rules;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value },
+ compare: function (other) {
+ if (other instanceof tree.Keyword) {
+ return other.value === this.value ? 0 : 1;
+ } else {
+ return -1;
+ }
+ }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+ this.filename = filename;
+ this.important = important;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments, this.important).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: e.index, filename: this.filename, stack: e.stack, call: this.index };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { type: 'Runtime',
+ message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index, filename: this.filename };
+ }
+ }
+ }
+ throw { type: 'Name',
+ message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index, filename: this.filename };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.condition = condition;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ evalParams: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []);
+
+ for (var i = 0, val; i < this.params.length; i++) {
+ if (this.params[i].name) {
+ if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+ } else {
+ throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ return frame;
+ },
+ eval: function (env, args, important) {
+ var frame = this.evalParams(env, args), context, _arguments = [], rules;
+
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ rules = important ?
+ this.rules.map(function (r) {
+ return new(tree.Rule)(r.name, r.value, '!important', r.index);
+ }) : this.rules.slice(0);
+
+ return new(tree.Ruleset)(null, rules).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len, frame;
+
+ if (argsLength < this.required) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+ if (this.condition && !this.condition.eval({
+ frames: [this.evalParams(env, args)].concat(env.frames)
+ })) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+ this.value = node;
+};
+tree.Paren.prototype = {
+ toCSS: function (env) {
+ return '(' + this.value.toCSS(env) + ')';
+ },
+ eval: function (env) {
+ return new(tree.Paren)(this.value.eval(env));
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return ('value' in v) ? v.value : v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+ this.inline = inline || false;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + (this.inline ? "" : ";");
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name,
+ this.value.eval(context),
+ this.important,
+ this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+ var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0));
+
+ ruleset.root = this.root;
+ ruleset.allowImports = this.allowImports;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root || ruleset.allowImports) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > rule.selectors[j].elements.length) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ this.joinSelectors(paths, context, this.selectors);
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ },
+
+ joinSelectors: function (paths, context, selectors) {
+ for (var s = 0; s < selectors.length; s++) {
+ this.joinSelector(paths, context, selectors[s]);
+ }
+ },
+
+ joinSelector: function (paths, context, selector) {
+ var before = [], after = [], beforeElements = [],
+ afterElements = [], hasParentSelector = false, el;
+
+ for (var i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ if (el.combinator.value.charAt(0) === '&') {
+ hasParentSelector = true;
+ }
+ if (hasParentSelector) afterElements.push(el);
+ else beforeElements.push(el);
+ }
+
+ if (! hasParentSelector) {
+ afterElements = beforeElements;
+ beforeElements = [];
+ }
+
+ if (beforeElements.length > 0) {
+ before.push(new(tree.Selector)(beforeElements));
+ }
+
+ if (afterElements.length > 0) {
+ after.push(new(tree.Selector)(afterElements));
+ }
+
+ for (var c = 0; c < context.length; c++) {
+ paths.push(before.concat(context[c]).concat(after));
+ }
+ }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ var len = this.elements.length,
+ olen = other.elements.length,
+ max = Math.min(len, olen);
+
+ if (len < olen) {
+ return false;
+ } else {
+ for (var i = 0; i < max; i++) {
+ if (this.elements[i].value !== other.elements[i].value) {
+ return false;
+ }
+ }
+ }
+ return true;
+};
+tree.Selector.prototype.eval = function (env) {
+ return new(tree.Selector)(this.elements.map(function (e) {
+ return e.eval(env);
+ }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (typeof(window) !== 'undefined' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { type: 'Name',
+ message: "variable " + name + " is undefined",
+ filename: this.file,
+ index: this.index };
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+tree.jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+
+})(require('./tree'));
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:' ||
+ location.protocol === 'chrome:' ||
+ location.protocol === 'chrome-extension:' ||
+ location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (e, root, _, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (e, root, _, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+ var css = tree.toCSS();
+ var style = styles[i];
+ style.type = 'text/css';
+ if (style.styleSheet) {
+ style.styleSheet.cssText = css;
+ } else {
+ style.innerHTML = css;
+ }
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^(https?|file):/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+ var filename = href.match(/([^\/]+)$/)[1];
+
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type,
+ filename: filename
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ css.media = sheet.media || 'screen';
+ css.id = id;
+ document.getElementsByTagName('head')[0].appendChild(css);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? false : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol) {
+ if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+ var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+ var elem = document.createElement('div'), timer, content, error = [];
+ var filename = e.filename || href;
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p>in <a href="' + filename + '">' + filename + "</a> ";
+
+ var errorline = function (e, i, classname) {
+ if (e.extract[i]) {
+ error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
+ .replace(/\{class\}/, classname)
+ .replace(/\{content\}/, e.extract[i]));
+ }
+ };
+
+ if (e.stack) {
+ content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+ } else if (e.extract) {
+ errorline(e, 0, '');
+ errorline(e, 1, 'line');
+ errorline(e, 2, '');
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ '<ul>' + error.join('') + '</ul>';
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #dd6666;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.line {',
+ 'color: #ff0000;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless121minjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.1.min.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.1.min.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.1.min.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+//
+// LESS - Leaner CSS v1.2.1
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function c(b){return a.less[b.split("/")[1]]}function m(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(k)&&(new d.Parser).parse(a[b].innerHTML||"",function(c,d){var e=d.toCSS(),f=a[b];f.type="text/css",f.styleSheet?f.styleSheet.cssText=e:f.innerHTML=e})}function n(a,b){for(var c=0;c<d.sheets.length;c++)o(d.sheets[c],a,b,d.sheets.length-(c+1))}function o(b,c,e,f){var g=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/,""),j=h&&h.getItem(i),k=h&&h.getItem(i+":timestamp"),l={css:j,timestamp:k};/^(https?|file):/.test(i)||(i.charAt(0)=="/"?i=a.location.protocol+"//"+a.location.host+i:i=g.slice(0,g.lastIndexOf("/")+1)+i);var m=i.match(/([^\/]+)$/)[1];s(b.href,b.type,function(a,g){if(!e&&l&&g&&(new Date(g)).valueOf()===(new Date(l.timestamp)).valueOf())r(l.css,b),c(nul
l,b,{local:!0,remaining:f});else try{(new d.Parser({optimization:d.optimization,paths:[i.replace(/[\w\.-]+$/,"")],mime:b.type,filename:m})).parse(a,function(d,e){if(d)return w(d,i);try{c(d,e,a,b,{local:!1,lastModified:g,remaining:f}),u(document.getElementById("less-error-message:"+q(i)))}catch(d){w(d,i)}})}catch(h){w(h,i)}},function(a,b){throw new Error("Couldn't load "+b+" ("+a+")")})}function q(a){return a.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\?.*$/,"").replace(/\.[^\.\/]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function r(a,b,c){var d,e=b.href?b.href.replace(/\?.*$/,""):"",f="less:"+(b.title||q(e));(d=document.getElementById(f))===null&&(d=document.createElement("style"),d.type="text/css",d.media=b.media||"screen",d.id=f,document.getElementsByTagName("head")[0]
.appendChild(d));if(d.styleSheet)try{d.styleSheet.cssText=a}catch(g){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(a){d.childNodes.length>0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&h&&(v("saving "+e+" to cache."),h.setItem(e,a),h.setItem(e+":timestamp",c))}function s(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var f=t(),h=g?!1:d.async;typeof f.overrideMimeType=="function"&&f.overrideMimeType("text/css"),f.open("GET",a,h),f.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),f.send(null),g?f.status===0||f.status>=200&&f.status<300?c(f.responseText):e(f.status,a):h?f.onreadystatechange
=function(){f.readyState==4&&i(f,c,e)}:i(f,c,e)}function t(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){return v("browser doesn't support AJAX."),null}}function u(a){return a&&a.parentNode.removeChild(a)}function v(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: "+a)}function w(a,b){var c="less-error-message:"+q(b),e='<li><label>{line}</label><pre class="{class}">{content}</pre></li>',f=document.createElement("div"),g,h,i=[],j=a.filename||b;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p>in <a href="'+j+'">'+j+"</a> ";var k=function(a,b,c){a.extract[b]&&i.push(e.replace(/\{line\}/,parseInt(a
.line)+(b-1)).replace(/\{class\}/,c).replace(/\{content\}/,a.extract[b]))};a.stack?h+="<br/>"+a.stack.split("\n").slice(1).join("<br/>"):a.extract&&(k(a,0,""),k(a,1,"line"),k(a,2,""),h+="on line "+a.line+", column "+(a.column+1)+":</p>"+"<ul>"+i.join("")+"</ul>"),f.innerHTML=h,r([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pr
e.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=setInterval(function(){document.body&&(document.getElementById(c
)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d<c;d++)d in this&&a.call(b,this[d],d,this)}),Array.prototype.map||(Array.prototype.map=function(a){var b=this.length>>>0,c=new Array(b),d=arguments[1];for(var e=0;e<b;e++)e in this&&(c[e]=a.call(d,this[e],e,this));return c}),Array.prototype.filter||(Array.prototype.filter=function(a){var b=[],c=arguments[1];for(var d=0;d<this.length;d++)a.call(c,this[d])&&b.push(this[d]);return b}),Array.prototype.reduce||(Array.prototype.reduce=function(a){var b=this.length>>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.length>=2)var d=argu
ments[1];else do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0);for(;c<b;c++)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){var b=this.length,c=arguments[1]||0;if(!b)return-1;if(c>=b)return-1;c<0&&(c+=b);for(;c<b;c++){if(!Object.prototype.hasOwnProperty.call(this,c))continue;if(a===this[c])return c}return-1}),Object.keys||(Object.keys=function(a){var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}),String.prototype.trim||(String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")});var d,f;typeof environment=="object"&&{}.toString.call(environment)==="[object Environment]"?(typeof a=="undefined"?d={}:d=a.less={},f=d.tree={},d.mode="rhino"):typeof a=="undefined"?(d=exports,f=c("./tree"),d.mode=&
quot;node"):(typeof a.less=="undefined"&&(a.less={}),d=a.less,f=a.less.tree={},d.mode="browser"),d.Parser=function(b){function t(){j=m[i],k=h,n=h}function u(){m[i]=j,h=k,n=h}function v(){h>n&&(m[i]=m[i].slice(h-n),n=h)}function w(a){var b,c,d,e,f,j,k,l;if(a instanceof Function)return a.call(o.parsers);if(typeof a=="string")b=g.charAt(h)===a?a:null,d=1,v();else{v();if(!(b=a.exec(m[i])))return null;d=b[0].length}if(b){l=h+=d,j=h+m[i].length-d;while(h<j){e=g.charCodeAt(h);if(e!==32&&e!==10&&e!==9)break;h++}return m[i]=m[i].slice(d+(h-l)),n=h,m[i].length===0&&i<m.length-1&&i++,typeof b=="string"?b:b.length===1?b[0]:b}}function x(a,b){var c=w(a);if(!!c)return c;y(b||(typeof a=="string"?"expected '"+a+"' got '"+g.charAt(h)+"'":"unexpected token"))}function y(a,b){throw{index:h,type:b||"Syntax",message:a}}function z(a){return type
of a=="string"?g.charAt(h)===a:a.test(m[i])?!0:!1}function A(a,b){return a.filename&&b.filename&&a.filename!==b.filename?o.imports.contents[a.filename]:g}function B(a,b){for(var c=a,d=-1;c>=0&&b.charAt(c)!=="\n";c--)d++;return{line:typeof a=="number"?(b.slice(0,a).match(/\n/g)||"").length:null,column:d}}function C(a,b){var c=A(a,b),d=B(a.index,c),e=d.line,f=d.column,g=c.split("\n");this.type=a.type||"Syntax",this.message=a.message,this.filename=a.filename||b.filename,this.index=a.index,this.line=typeof e=="number"?e+1:null,this.callLine=a.call&&B(a.call,c)+1,this.callExtract=g[B(a.call,c)],this.stack=a.stack,this.column=f,this.extract=[g[e-1],g[e],g[e+1]]}var g,h,i,j,k,l,m,n,o,q=this,r=function(){},s=this.imports={paths:b&&b.paths||[],queue:[],files:{},contents:{},mime:b&&b.mime,error:null,push:function(a,c){var e=this;this.queue.push(a),d.Parser.importer(a,this.p
aths,function(b,d,f){e.queue.splice(e.queue.indexOf(a),1),e.files[a]=d,e.contents[a]=f,b&&!e.error&&(e.error=b),c(b,d),e.queue.length===0&&r()},b)}};return this.env=b=b||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.filename=this.env.filename||null,o={imports:s,parse:function(a,e){var j,k,p,q,s,t,u=[],v,x=null;h=i=n=l=0,m=[],g=a.replace(/\r\n/g,"\n"),m=function(a){var c=0,d=/[^"'`\{\}\/\(\)]+/g,e=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,f=0,h,i=a[0],j,k;for(var l=0,m,n;l<g.length;l++){d.lastIndex=l,(h=d.exec(g))&&h.index===l&&(l+=h[0].length,i.push(h[0])),m=g.charAt(l),e.lastIndex=l,!k&&!j&&m==="/"&&(n=g.charAt(l+1),(n==="/"||n==="*")&&(h=e.exec(g))&&h.index===l&&(l+=h[0].length,i.push(h[0]),m=g.charAt(l)));if(m==="{"&&!k&&!j)f++,i.push(m);else if(m==="}"&&!k&&
amp;!j)f--,i.push(m),a[++c]=i=[];else if(m==="("&&!k&&!j)i.push(m),j=!0;else if(m===")"&&!k&&j)i.push(m),j=!1;else{if(m==='"'||m==="'"||m==="`")k?k=k===m?!1:k:k=m;i.push(m)}}if(f>0)throw{type:"Syntax",message:"Missing closing `}`",filename:b.filename};return a.map(function(a){return a.join("")})}([[]]);try{j=new f.Ruleset([],w(this.parsers.primary)),j.root=!0}catch(y){return e(new C(y,b))}j.toCSS=function(a){var e,g,h;return function(e,g){var h=[],i;e=e||{},typeof g=="object"&&!Array.isArray(g)&&(g=Object.keys(g).map(function(a){var b=g[a];return b instanceof f.Value||(b instanceof f.Expression||(b=new f.Expression([b])),b=new f.Value([b])),new f.Rule("@"+a,b,!1,0)}),h=[new f.Ruleset(null,g)]);try{var j=a.call(this,{frames:h}).toCSS([],{compress:e.compress||!1})}catch(k){throw new C(k,b)}if(i=o.imports.error)throw i instanceof C?i:new C(i,
b);return e.yuicompress&&d.mode==="node"?c("./cssmin").compressor.cssmin(j):e.compress?j.replace(/(\s)+/g,"$1"):j}}(j.eval);if(h<g.length-1){h=l,t=g.split("\n"),s=(g.slice(0,h).match(/\n/g)||"").length+1;for(var z=h,A=-1;z>=0&&g.charAt(z)!=="\n";z--)A++;x={type:"Parse",message:"Syntax Error on line "+s,index:h,filename:b.filename,line:s,column:A,extract:[t[s-2],t[s-1],t[s]]}}this.imports.queue.length>0?r=function(){e(x,j)}:e(x,j)},parsers:{primary:function(){var a,b=[];while((a=w(this.mixin.definition)||w(this.rule)||w(this.ruleset)||w(this.mixin.call)||w(this.comment)||w(this.directive))||w(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(g.charAt(h)!=="/")return;if(g.charAt(h+1)==="/")return new f.Comment(w(/^\/\/.*/),!0);if(a=w(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new f.Comment(a)},entities:{quoted:function(){var a,b=h,c;g.charAt
(b)==="~"&&(b++,c=!0);if(g.charAt(b)!=='"'&&g.charAt(b)!=="'")return;c&&w("~");if(a=w(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new f.Quoted(a[0],a[1]||a[2],c)},keyword:function(){var a;if(a=w(/^[_A-Za-z-][_A-Za-z0-9-]*/))return f.colors.hasOwnProperty(a)?new f.Color(f.colors[a].slice(1)):new f.Keyword(a)},call:function(){var a,c,d=h;if(!(a=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(m[i])))return;a=a[1].toLowerCase();if(a==="url")return null;h+=a.length;if(a==="alpha")return w(this.alpha);w("("),c=w(this.entities.arguments);if(!w(")"))return;if(a)return new f.Call(a,c,d,b.filename)},arguments:function(){var a=[],b;while(b=w(this.entities.assignment)||w(this.expression)){a.push(b);if(!w(","))break}return a},literal:function(){return w(this.entities.dimension)||w(this.entities.color)||w(this.entities.quoted)},assignment:function(){var a,b;if((a=w(/^\w+(
?=\s?=)/i))&&w("=")&&(b=w(this.entity)))return new f.Assignment(a,b)},url:function(){var a;if(g.charAt(h)!=="u"||!w(/^url\(/))return;return a=w(this.entities.quoted)||w(this.entities.variable)||w(this.entities.dataURI)||w(/^[-\w%@$\/.&=:;#+?~]+/)||"",x(")"),new f.URL(a.value||a.data||a instanceof f.Variable?a:new f.Anonymous(a),s.paths)},dataURI:function(){var a;if(w(/^data:/)){a={},a.mime=w(/^[^\/]+\/[^,;)]+/)||"",a.charset=w(/^;\s*charset=[^,;)]+/)||"",a.base64=w(/^;\s*base64/)||"",a.data=w(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var a,c=h;if(g.charAt(h)==="@"&&(a=w(/^@@?[\w-]+/)))return new f.Variable(a,c,b.filename)},color:function(){var a;if(g.charAt(h)==="#"&&(a=w(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new f.Color(a[1])},dimension:function(){var a,b=g.charCodeAt(h);if(b>57||b<45||b===47)return;if(a=w(/^(-?\d*\.?\d+)(px|%|em|re
m|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new f.Dimension(a[1],a[2])},javascript:function(){var a,b=h,c;g.charAt(b)==="~"&&(b++,c=!0);if(g.charAt(b)!=="`")return;c&&w("~");if(a=w(/^`([^`]*)`/))return new f.JavaScript(a[1],h,c)}},variable:function(){var a;if(g.charAt(h)==="@"&&(a=w(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!z(/^[@\w.%-]+\/[@\w.-]+/))return;if((a=w(this.entity))&&w("/")&&(b=w(this.entity)))return new f.Shorthand(a,b)},mixin:{call:function(){var a=[],c,d,e,i=h,j=g.charAt(h),k=!1;if(j!=="."&&j!=="#")return;while(c=w(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))a.push(new f.Element(d,c,h)),d=w(">");w("(")&&(e=w(this.entities.arguments))&&w(")"),w(this.important)&&(k=!0);if(a.length>0&&(w(";")||z("}")))return new f.mixin.Cal
l(a,e,i,b.filename,k)},definition:function(){var a,b=[],c,d,e,i,j;if(g.charAt(h)!=="."&&g.charAt(h)!=="#"||z(/^[^{]*(;|})/))return;t();if(c=w(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=c[1];while(e=w(this.entities.variable)||w(this.entities.literal)||w(this.entities.keyword)){e instanceof f.Variable?w(":")?(i=x(this.expression,"expected expression"),b.push({name:e.name,value:i})):b.push({name:e.name}):b.push({value:e});if(!w(","))break}x(")"),w(/^when/)&&(j=x(this.conditions,"expected condition")),d=w(this.block);if(d)return new f.mixin.Definition(a,b,d,j);u()}}},entity:function(){return w(this.entities.literal)||w(this.entities.variable)||w(this.entities.url)||w(this.entities.call)||w(this.entities.keyword)||w(this.entities.javascript)||w(this.comment)},end:function(){return w(";")||z("}")},alpha:function(){var a;if(!w(/^\(opacity=/i))return;if(a=w(/^\d+
/)||w(this.entities.variable))return x(")"),new f.Alpha(a)},element:function(){var a,b,c,d;c=w(this.combinator),a=w(/^(?:\d+\.\d+|\d+)%/)||w(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||w("*")||w(this.attribute)||w(/^\([^)@]+\)/),a||w("(")&&(d=w(this.entities.variable))&&w(")")&&(a=new f.Paren(d));if(a)return new f.Element(c,a,h);if(c.value&&c.value.charAt(0)==="&")return new f.Element(c,null,h)},combinator:function(){var a,b=g.charAt(h);if(b===">"||b==="+"||b==="~"){h++;while(g.charAt(h)===" ")h++;return new f.Combinator(b)}if(b==="&"){a="&",h++,g.charAt(h)===" "&&(a="& ");while(g.charAt(h)===" ")h++;return new f.Combinator(a)}if(b===":"&&g.charAt(h+1)===":"){h+=2;while(g.charAt(h)===" ")h++;return new f.Combinator("::"
;)}return g.charAt(h-1)===" "?new f.Combinator(" "):new f.Combinator(null)},selector:function(){var a,b,c=[],d,e;while(b=w(this.element)){d=g.charAt(h),c.push(b);if(d==="{"||d==="}"||d===";"||d===",")break}if(c.length>0)return new f.Selector(c)},tag:function(){return w(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||w("*")},attribute:function(){var a="",b,c,d;if(!w("["))return;if(b=w(/^[a-zA-Z-]+/)||w(this.entities.quoted))(d=w(/^[|~*$^]?=/))&&(c=w(this.entities.quoted)||w(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!w("]"))return;if(a)return"["+a+"]"},block:function(){var a;if(w("{")&&(a=w(this.primary))&&w("}"))return a},ruleset:function(){var a=[],b,c,d;t();while(b=w(this.selector)){a.push(b),w(this.comment);if(!w(","))break;w(this.comment)}if(a.length>0&&(c=w(this.block)))return new f.Rules
et(a,c);l=h,u()},rule:function(){var a,b,c=g.charAt(h),d,e;t();if(c==="."||c==="#"||c==="&")return;if(a=w(this.variable)||w(this.property)){a.charAt(0)!="@"&&(e=/^([^@+\/'"*`(;{}-]*);/.exec(m[i]))?(h+=e[0].length-1,b=new f.Anonymous(e[1])):a==="font"?b=w(this.font):b=w(this.value),d=w(this.important);if(b&&w(this.end))return new f.Rule(a,b,d,k);l=h,u()}},"import":function(){var a,b,c=h;if(w(/^@import\s+/)&&(a=w(this.entities.quoted)||w(this.entities.url))){b=w(this.mediaFeatures);if(w(";"))return new f.Import(a,s,b,c)}},mediaFeature:function(){var a=[];do if(e=w(this.entities.keyword))a.push(e);else if(w("(")){p=w(this.property),e=w(this.entity);if(!w(")"))return null;if(p&&e)a.push(new f.Paren(new f.Rule(p,e,null,h,!0)));else{if(!e)return null;a.push(new f.Paren(e))}}while(e);if(a.length>0)return new f.Expression(a)},mediaFeatures:function(){var a,b=
[];while(a=w(this.mediaFeature)){b.push(a);if(!w(","))break}return b.length>0?b:null},media:function(){var a;if(w(/^@media/)){a=w(this.mediaFeatures);if(rules=w(this.block))return new f.Directive("@media",rules,a)}},directive:function(){var a,b,c,d,e,i;if(g.charAt(h)!=="@")return;if(b=w(this["import"])||w(this.media))return b;if(a=w(/^@page|@keyframes/)||w(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)){d=(w(/^[^{]+/)||"").trim();if(c=w(this.block))return new f.Directive(a+" "+d,c)}else if(a=w(/^@[-a-z]+/))if(a==="@font-face"){if(c=w(this.block))return new f.Directive(a,c)}else if((b=w(this.entity))&&w(";"))return new f.Directive(a,b)},font:function(){var a=[],b=[],c,d,e,g;while(g=w(this.shorthand)||w(this.entity))b.push(g);a.push(new f.Expression(b));if(w(","))while(g=w(this.expression)){a.push(g);if(!w(","))break}return new f.Value(a)},value:function(){var a,b=[],c;while(a=w(
this.expression)){b.push(a);if(!w(","))break}if(b.length>0)return new f.Value(b)},important:function(){if(g.charAt(h)==="!")return w(/^! *important/)},sub:function(){var a;if(w("(")&&(a=w(this.expression))&&w(")"))return a},multiplication:function(){var a,b,c,d;if(a=w(this.operand)){while(!z(/^\/\*/)&&(c=w("/")||w("*"))&&(b=w(this.operand)))d=new f.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,b,c,d;if(a=w(this.multiplication)){while((c=w(/^[-+]\s+/)||g.charAt(h-1)!=" "&&(w("+")||w("-")))&&(b=w(this.multiplication)))d=new f.Operation(c,[d||a,b]);return d||a}},conditions:function(){var a,b,c=h,d;if(a=w(this.condition)){while(w(",")&&(b=w(this.condition)))d=new f.Condition("or",d||a,b,c);return d||a}},condition:function(){var a,b,c,d,e=h,g=!1;w(/^not/)&&(g=!0),x("(");if(a=w(this.additi
on)||w(this.entities.keyword)||w(this.entities.quoted))return(d=w(/^(?:>=|=<|[<=>])/))?(b=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))?c=new f.Condition(d,a,b,e,g):y("expected expression"):c=new f.Condition("=",a,new f.Keyword("true"),e,g),x(")"),w(/^and/)?new f.Condition("and",c,w(this.condition)):c},operand:function(){var a,b=g.charAt(h+1);g.charAt(h)==="-"&&(b==="@"||b==="(")&&(a=w("-"));var c=w(this.sub)||w(this.entities.dimension)||w(this.entities.color)||w(this.entities.variable)||w(this.entities.call);return a?new f.Operation("*",[new f.Dimension(-1),c]):c},expression:function(){var a,b,c=[],d;while(a=w(this.addition)||w(this.entity))c.push(a);if(c.length>0)return new f.Expression(c)},property:function(){var a;if(a=w(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}};if(d.mode==="browser"||d.mode==="rhino")d.Par
ser.importer=function(a,b,c,d){a.charAt(0)!=="/"&&b.length>0&&(a=b[0]+a),o({href:a,title:a,type:d.mime},c,!0)};(function(a){function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function d(a){return Math.min(1,Math.max(0,a))}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){return a=a<0?a+1:a>1?a-1:a,a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.
Dimension(Math.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();return e.s+=c.value/100,e.s=d(e.s),b(e)},desaturate:function(a,c){var e=a.toHSL();return e.s-=c.value/100,e.s=d(e.s),b(e)},lighten:function(a,c){var e=a.toHSL();return e.l+=c.value/100,e.l=d(e.l),b(e)},darken:function(a,c){var e=a.toHSL();return e.l-=c.value/100,e.l=d(e.l),b(e)},fadein:function(a,c){var e=a.toHSL();return e.a+=c.value/100,e.a=d(e.a),b(e)},fadeout:function(a,c){var e=a.toHSL();return e.a-=c.value/100,e.a=d(e.a),b(e)},fade:function(a,c){var e=a.toHSL();return e.a=c.value/100,e.a=d(e.a),b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;return d.h=e<0?360+e:e,b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+
g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e<c.length;e++)d=d.replace(/%[sda]/i,function(a){var b=a.match(/s/i)?c[e].value:c[e].toCSS();return a.match(/[A-Z]$/)?encodeURIComponent(b):b});return d=d.replace(/%%/g,"%"),new a.Quoted('"'+d+'"',d)},round:function(a){return this._math("round",a)},ceil:function(a){return this._math("ceil",a)},floor:function(a){return th
is._math("floor",a)},_math:function(b,d){if(d instanceof a.Dimension)return new a.Dimension(Math[b](c(d)),d.unit);if(typeof d=="number")return Math[b](d);throw{type:"Argument",message:"argument must be a number"}},argb:function(b){return new a.Anonymous(b.toARGB())},percentage:function(b){return new a.Dimension(b.value*100,"%")},color:function(b){if(b instanceof a.Quoted)return new a.Color(b.value.slice(1));throw{type:"Argument",message:"argument must be a string"}},iscolor:function(b){return this._isa(b,a.Color)},isnumber:function(b){return this._isa(b,a.Dimension)},isstring:function(b){return this._isa(b,a.Quoted)},iskeyword:function(b){return this._isa(b,a.Keyword)},isurl:function(b){return this._isa(b,a.URL)},ispixel:function(b){return b instanceof a.Dimension&&b.unit==="px"?a.True:a.False},ispercentage:function(b){return b instanceof a.Dimension&&b.unit==="%"?a.True:a.False
},isem:function(b){return b instanceof a.Dimension&&b.unit==="em"?a.True:a.False},_isa:function(b,c){return b instanceof c?a.True:a.False}}})(c("./tree")),function(a){a.colors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkha
ki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indig
o:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",med
iumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagree
n:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"}}(c("./tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(a){return this.value.eval&&(this.value=this.value.eval(a)),this}}}(c("../tree")),function(a){a.Anonymous=function(a){this.value=a.value||a},a.Anonym
ous.prototype={toCSS:function(){return this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Assignment=function(a,b){this.key=a,this.value=b},a.Assignment.prototype={toCSS:function(){return this.key+"="+(this.value.toCSS?this.value.toCSS():this.value)},eval:function(a){return this.value.eval&&(this.value=this.value.eval(a)),this}}}(c("../tree")),function(a){a.Call=function(a,b,c,d){this.name=a,this.args=b,this.index=c,this.filename=d},a.Call.prototype={eval:function(b){var c=this.args.map(function(a){return a.eval(b)});if(!(this.name in a.functions))return new a.Anonymous(this.name+"("+c.map(function(a){return a.toCSS()}).join(", ")+")");try{return a.functions[this.name].apply(a.functions,c)}catch(d){throw{type:d.type||"Runtime",message:"error evaluating function `"+this.name+"`"+(d.message?": "+d.message:""),index:this.index,filename:this.filename}
}},toCSS:function(a){return this.eval(a).toCSS()}}}(c("../tree")),function(a){a.Color=function(a,b){Array.isArray(a)?this.rgb=a:a.length==6?this.rgb=a.match(/.{2}/g).map(function(a){return parseInt(a,16)}):this.rgb=a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha=typeof b=="number"?b:1},a.Color.prototype={eval:function(){return this},toCSS:function(){return this.alpha<1?"rgba("+this.rgb.map(function(a){return Math.round(a)}).concat(this.alpha).join(", ")+")":"#"+this.rgb.map(function(a){return a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,
h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);switch(e){case a:g=(b-c)/j+(b<c?6:0);break;case b:g=(c-a)/j+2;break;case c:g=(a-b)/j+4}g/=6}return{h:g*360,s:h,l:i,a:d}},toARGB:function(){var a=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+a.map(function(a){return a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")}}}(c("../tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Condition=function(a,b,c,d,e){this.op=a.trim(),this.lvalue=b,this.rvalue=c,this.index=d,this.negate=e},a.Condition.prototype.eval=function(a){var b=this.lvalue.eval(a),c=this.rvalue.eval(a),d=this.index,e,e=function(a){switch(a){case"and":return b&&c;case"or":return b||c;default:if(b.compare)e=b.compare(c);els
e{if(!c.compare)throw{type:"Type",message:"Unable to perform comparison",index:d};e=c.compare(b)}switch(e){case-1:return a==="<"||a==="=<";case 0:return a==="="||a===">="||a==="=<";case 1:return a===">"||a===">="}}}(this.op);return this.negate?!e:e}}(c("../tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)},compare:function(b){return b instanceof a.Dimension?b.value>this.value?-1:b.value<this.value?1:0:-1}}}(c("../tree")),function(a){a.Directive=function(b,c,d){this.name=b,this.features=d&&new a.Value(d),Array.isArray(c)?(this.rulese
t=new a.Ruleset([],c),this.ruleset.allowImports=!0):this.value=c},a.Directive.prototype={toCSS:function(a,b){var c=this.features?" "+this.features.toCSS(b):"";return this.ruleset?(this.ruleset.root=!0,this.name+c+(b.compress?"{":" {\n ")+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n ")+(b.compress?"}":"\n}\n")):this.name+" "+this.value.toCSS()+";\n"},eval:function(a){return this.features=this.features&&this.features.eval(a),a.frames.unshift(this),this.ruleset=this.ruleset&&this.ruleset.eval(a),a.frames.shift(),this},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(c("../tree")),function(a){a.Element=function(b,c,d){this.combinator=b instanceof a.Combinator?b:new a.Combinator(b),t
ypeof c=="string"?this.value=c.trim():c?this.value=c:this.value="",this.index=d},a.Element.prototype.eval=function(b){return new a.Element(this.combinator,this.value.eval?this.value.eval(b):this.value,this.index)},a.Element.prototype.toCSS=function(a){return this.combinator.toCSS(a||{})+(this.value.toCSS?this.value.toCSS(a):this.value)},a.Combinator=function(a){a===" "?this.value=" ":a==="& "?this.value="& ":this.value=a?a.trim():""},a.Combinator.prototype.toCSS=function(a){return{"":""," ":" ","&":"","& ":" ",":":" :","::":"::","+":a.compress?"+":" + ","~":a.compress?"~":" ~ ",">":a.compress?">":" > "}[this.value]}}(c("../tree")),function(a){a.Expression=function(a){this.v
alue=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS?b.toCSS(a):""}).join(" ")}}}(c("../tree")),function(a){a.Import=function(b,c,d,e){var f=this;this.index=e,this._path=b,this.features=d&&new a.Value(d),b instanceof a.Quoted?this.path=/\.(le?|c)ss(\?.*)?$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value||b.value,this.css=/css(\?.*)?$/.test(this.path),this.css||c.push(this.path,function(b,c){b&&(b.index=e),f.root=c||new a.Ruleset([],[])})},a.Import.prototype={toCSS:function(a){var b=this.features?" "+this.features.toCSS(a):"";return this.css?"@import "+this._path.toCSS()+b+";\n":""},eval:function(b){var c,d=this.features&&this.features.eval(b);if(this.cs
s)return this;c=new a.Ruleset([],this.root.rules.slice(0));for(var e=0;e<c.rules.length;e++)c.rules[e]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[e,1].concat(c.rules[e].eval(b)));return this.features?new a.Directive("@media",c.rules,this.features.value):c.rules}}}(c("../tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify((new a.Variable("@"+e,d.index)).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: `"+
+f+"`",index:this.index}}for(var h in b.frames[0].variables())e[h.slice(1)]={value:b.frames[0].variables()[h].value,toJS:function(){return this.value.eval(b).toCSS()}};try{c=f.call(e)}catch(g){throw{message:"JavaScript evaluation error: '"+g.name+": "+g.message+"'",index:this.index}}return typeof c=="string"?new a.Quoted('"'+c+'"',c,this.escaped,this.index):Array.isArray(c)?new a.Anonymous(c.join(", ")):new a.Anonymous(c)}}}(c("../tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value},compare:function(b){return b instanceof a.Keyword?b.value===this.value?0:1:-1}},a.True=new a.Keyword("true"),a.False=new a.Keyword("false")}(c("../tree")),function(a){a.mixin={},a.mixin.Call=function(b,c,d,e,f){this.selector=new a.Selector(b),this.arguments=c,this.index=d,this.filename=e,this.important=f},a.mi
xin.Call.prototype={eval:function(a){var b,c,d=[],e=!1;for(var f=0;f<a.frames.length;f++)if((b=a.frames[f].find(this.selector)).length>0){c=this.arguments&&this.arguments.map(function(b){return b.eval(a)});for(var g=0;g<b.length;g++)if(b[g].match(c,a))try{Array.prototype.push.apply(d,b[g].eval(a,this.arguments,this.important).rules),e=!0}catch(h){throw{message:h.message,index:h.index,filename:this.filename,stack:h.stack,call:this.index}}if(e)return d;throw{type:"Runtime",message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(a){return a.toCSS()}).join(", ")+")`",index:this.index,filename:this.filename}}throw{type:"Name",message:this.selector.toCSS().trim()+" is undefined",index:this.index,filename:this.filename}}},a.mixin.Definition=function(b,c,d,e){this.name=b,this.selectors=[new a.Selector([new a.Element(null,b)])],this.params=c,this.condit
ion=e,this.arity=c.length,this.rules=d,this._lookups={},this.required=c.reduce(function(a,b){return!b.name||b.name&&!b.value?a+1:a},0),this.parent=a.Ruleset.prototype,this.frames=[]},a.mixin.Definition.prototype={toCSS:function(){return""},variable:function(a){return this.parent.variable.call(this,a)},variables:function(){return this.parent.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},evalParams:function(b,c){var d=new a.Ruleset(null,[]);for(var e=0,f;e<this.params.length;e++)if(this.params[e].name){if(!(f=c&&c[e]||this.params[e].value))throw{type:"Runtime",message:"wrong number of arguments for "+this.name+" ("+c.length+" for "+this.arity+")"};d.rules.unshift(new a.Rule(this.params[e].name,f.eval(b)))}return d},eval:function(b,c,d){var e=this.evalParams(b,c),f,g=[],h;for(var i=0;i<Math.max(this.params.
length,c&&c.length);i++)g.push(c[i]||this.params[i].value);return e.rules.unshift(new a.Rule("@arguments",(new a.Expression(g)).eval(b))),h=d?this.rules.map(function(b){return new a.Rule(b.name,b.value,"!important",b.index)}):this.rules.slice(0),(new a.Ruleset(null,h)).eval({frames:[this,e].concat(this.frames,b.frames)})},match:function(a,b){var c=a&&a.length||0,d,e;if(c<this.required)return!1;if(this.required>0&&c>this.params.length)return!1;if(this.condition&&!this.condition.eval({frames:[this.evalParams(b,a)].concat(b.frames)}))return!1;d=Math.min(c,this.arity);for(var f=0;f<d;f++)if(!this.params[f].name&&a[f].eval(b).toCSS()!=this.params[f].value.eval(b).toCSS())return!1;return!0}}}(c("../tree")),function(a){a.Operation=function(a,b){this.op=a.trim(),this.operands=b},a.Operation.prototype.eval=function(b){var c=this.operands[0].eval(b),d=this.operands[1].eval(b),e;if(c instanceof a.Dimension&&a
mp;d instanceof a.Color){if(this.op!=="*"&&this.op!=="+")throw{name:"OperationError",message:"Can't substract or divide a color from a number"};e=d,d=c,c=e}return c.operate(this.op,d)},a.operate=function(a,b,c){switch(a){case"+":return b+c;case"-":return b-c;case"*":return b*c;case"/":return b/c}}}(c("../tree")),function(a){a.Paren=function(a){this.value=a},a.Paren.prototype={toCSS:function(a){return"("+this.value.toCSS(a)+")"},eval:function(b){return new a.Paren(this.value.eval(b))}}}(c("../tree")),function(a){a.Quoted=function(a,b,c,d){this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d},a.Quoted.prototype={toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(b){var c=this,d=this.value.replace(/`([^`]+)`/g,function(d,e){return(new a.JavaScript(e,c.index,!0)).eval(b).value}).replace(/@\{(
[\w-]+)\}/g,function(d,e){var f=(new a.Variable("@"+e,c.index)).eval(b);return"value"in f?f.value:f.toCSS()});return new a.Quoted(this.quote+d+this.quote,d,this.escaped,this.index)}}}(c("../tree")),function(a){a.Rule=function(b,c,d,e,f){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.index=e,this.inline=f||!1,b.charAt(0)==="@"?this.variable=!0:this.variable=!1},a.Rule.prototype.toCSS=function(a){return this.variable?"":this.name+(a.compress?":":": ")+this.value.toCSS(a)+this.important+(this.inline?"":";")},a.Rule.prototype.eval=function(b){return new a.Rule(this.name,this.value.eval(b),this.important,this.index,this.inline)},a.Shorthand=function(a,b){this.a=a,this.b=b},a.Shorthand.prototype={toCSS:function(a){return this.a.toCSS(a)+"/"+this.b.toCSS(a)},eval:function(){return this}}}(c("../tree")),functi
on(a){a.Ruleset=function(a,b){this.selectors=a,this.rules=b,this._lookups={}},a.Ruleset.prototype={eval:function(b){var c=this.selectors&&this.selectors.map(function(a){return a.eval(b)}),d=new a.Ruleset(c,this.rules.slice(0));d.root=this.root,d.allowImports=this.allowImports,b.frames.unshift(d);if(d.root||d.allowImports)for(var e=0;e<d.rules.length;e++)d.rules[e]instanceof a.Import&&Array.prototype.splice.apply(d.rules,[e,1].concat(d.rules[e].eval(b)));for(var e=0;e<d.rules.length;e++)d.rules[e]instanceof a.mixin.Definition&&(d.rules[e].frames=b.frames.slice(0));for(var e=0;e<d.rules.length;e++)d.rules[e]instanceof a.mixin.Call&&Array.prototype.splice.apply(d.rules,[e,1].concat(d.rules[e].eval(b)));for(var e=0,f;e<d.rules.length;e++)f=d.rules[e],f instanceof a.mixin.Definition||(d.rules[e]=f.eval?f.eval(b):f);return b.frames.shift(),d},match:function(a){return!a||a.length===0},variables:function(){return this._variables?this._variables:th
is._variables=this.rules.reduce(function(b,c){return c instanceof a.Rule&&c.variable===!0&&(b[c.name]=c),b},{})},variable:function(a){return this.variables()[a]},rulesets:function(){return this._rulesets?this._rulesets:this._rulesets=this.rules.filter(function(b){return b instanceof a.Ruleset||b instanceof a.mixin.Definition})},find:function(b,c){c=c||this;var d=[],e,f,g=b.toCSS();return g in this._lookups?this._lookups[g]:(this.rulesets().forEach(function(e){if(e!==c)for(var g=0;g<e.selectors.length;g++)if(f=b.match(e.selectors[g])){b.elements.length>e.selectors[g].elements.length?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}}),this._lookups[g]=d)},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;this.root||(b.length===0?g=this.selectors.map(function(a){return[a]}):this.joinSelectors(g,b,this.selectors));for(var j=0;j<this.rules.length;j++)i=this.rules[j],i.rules||i instanceof a.Directive?f.push(i.toCSS(g,c)):i
instanceof a.Comment?i.silent||(this.root?f.push(i.toCSS(c)):e.push(i.toCSS(c))):i.toCSS&&!i.variable?e.push(i.toCSS(c)):i.value&&!i.variable&&e.push(i.value.toString());return f=f.join(""),this.root?d.push(e.join(c.compress?"":"\n")):e.length>0&&(h=g.map(function(a){return a.map(function(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":g.length>3?",\n":", "),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f),d.join("")+(c.compress?"\n":"")},joinSelectors:function(a,b,c){for(var d=0;d<c.length;d++)this.joinSelector(a,b,c[d])},joinSelector:function(b,c,d){var e=[],f=[],g=[],h=[],i=!1,j;for(var k=0;k<d.elements.length;k++)j=d.elements[k],j.combinator.value.charAt(0)==="&"&&(i=!0),i?h.push(j):g.push(j);
i||(h=g,g=[]),g.length>0&&e.push(new a.Selector(g)),h.length>0&&f.push(new a.Selector(h));for(var l=0;l<c.length;l++)b.push(e.concat(c[l]).concat(f))}}}(c("../tree")),function(a){a.Selector=function(a){this.elements=a,this.elements[0].combinator.value===""&&(this.elements[0].combinator.value=" ")},a.Selector.prototype.match=function(a){var b=this.elements.length,c=a.elements.length,d=Math.min(b,c);if(b<c)return!1;for(var e=0;e<d;e++)if(this.elements[e].value!==a.elements[e].value)return!1;return!0},a.Selector.prototype.eval=function(b){return new a.Selector(this.elements.map(function(a){return a.eval(b)}))},a.Selector.prototype.toCSS=function(a){return this._css?this._css:this._css=this.elements.map(function(b){return typeof b=="string"?" "+b.trim():b.toCSS(a)}).join("")}}(c("../tree")),function(b){b.URL=function(b,c){b.data?this.attrs=b:(typeof a!="undefined"&&
amp;!/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(b.value)&&c.length>0&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("../tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("../tree")),function(a){a.Variable=function(a,b,c){this.name=a,this.index=b,this.file=c},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.ind
exOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{type:"Name",message:"variable "+e+" is undefined",filename:this.file,index:this.index}}}}(c("../tree")),function(a){a.find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null},a.jsify=function(a){return Array.isArray(a.value)&&a.value.length>1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)}}(c("./tree"));var g=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||g?&quo
t;development":"production"),d.async=!1,d.poll=d.poll||(g?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&n(function(a,b,c,d,e){b&&r(b.toCSS(),d,e.lastModified)})},d.poll)):d.optimization=3;var h;try{h=typeof a.localStorage=="undefined"?null:a.localStorage}catch(i){h=null}var j=document.getElementsByTagName("link"),k=/^text\/(x-)?less$/;d.sheets=[];for(var l=0;l<j.length;l++)(j[l].rel==="stylesheet/less"||j[l].rel.match(/stylesheet/)&&j[l].type.match(k))&&d.sheets.push(j[l]);d.refresh=function(a){var b,c;b=c=new Date,n(function(a,d,e,f,g){g.local?v("loading "+f.href+" from cache."):(v("parsed "+f.href+" successfully."),r(d.toCSS(),f,g.lastModified)),v("css for &q
uot;+f.href+" generated in "+(new Date-c)+"ms"),g.remaining===0&&v("css generated in "+(new Date-b)+"ms"),c=new Date},a),m()},d.refreshStyles=m,d.refresh(d.env==="development")})(window);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless122js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.2.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.2.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.2.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3337 @@
</span><ins>+//
+// LESS - Leaner CSS v1.2.2
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
+// amd.js
+//
+// Define Less as an AMD module.
+if (typeof define === "function" && define.amd) {
+ define("less", [], function () { return less; } );
+}
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+ // Rhino
+ // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+ if (typeof(window) === 'undefined') { less = {} }
+ else { less = window.less = {} }
+ tree = less.tree = {};
+ less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+ // Node.js
+ less = exports,
+ tree = require('./tree');
+ less.mode = 'node';
+} else {
+ // Browser
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+ less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ contents: {}, // Holds the imported file contents
+ mime: env && env.mime, // MIME type of .less files
+ error: null, // Error in parsing/evaluating an import
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (e, root, contents) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+ that.contents[path] = contents;
+
+ if (e && !that.error) { that.error = e }
+ callback(e, root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ function expect(arg, msg) {
+ var result = $(arg);
+ if (! result) {
+ error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+ : "unexpected token"));
+ } else {
+ return result;
+ }
+ }
+
+ function error(msg, type) {
+ throw { index: i, type: type || 'Syntax', message: msg };
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ function basename(pathname) {
+ if (less.mode === 'node') {
+ return require('path').basename(pathname);
+ } else {
+ return pathname.match(/[^\/]+$/)[0];
+ }
+ }
+
+ function getInput(e, env) {
+ if (e.filename && env.filename && (e.filename !== env.filename)) {
+ return parser.imports.contents[basename(e.filename)];
+ } else {
+ return input;
+ }
+ }
+
+ function getLocation(index, input) {
+ for (var n = index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ return { line: typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+ column: column };
+ }
+
+ function LessError(e, env) {
+ var input = getInput(e, env),
+ loc = getLocation(e.index, input),
+ line = loc.line,
+ col = loc.column,
+ lines = input.split('\n');
+
+ this.type = e.type || 'Syntax';
+ this.message = e.message;
+ this.filename = e.filename || env.filename;
+ this.index = e.index;
+ this.line = typeof(line) === 'number' ? line + 1 : null;
+ this.callLine = e.call && (getLocation(e.call, input) + 1);
+ this.callExtract = lines[getLocation(e.call, input)];
+ this.stack = e.stack;
+ this.column = col;
+ this.extract = [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ];
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)\\]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`\\\r\n]|\\.)*)`/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = string.lastIndex = i;
+
+ if (match = string.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+
+ if (!inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ switch (c) {
+ case '{': if (! inParam) { level ++; chunk.push(c); break }
+ case '}': if (! inParam) { level --; chunk.push(c); chunks[++j] = chunk = []; break }
+ case '(': if (! inParam) { inParam = true; chunk.push(c); break }
+ case ')': if ( inParam) { inParam = false; chunk.push(c); break }
+ default: chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ error = new(LessError)({
+ index: i,
+ type: 'Parse',
+ message: "missing closing `}`",
+ filename: env.filename
+ }, env);
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ if (error) {
+ return callback(error);
+ }
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ try {
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+ } catch (e) {
+ return callback(new(LessError)(e, env));
+ }
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [], importError;
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ throw new(LessError)(e, env);
+ }
+
+ if ((importError = parser.imports.error)) { // Check if there was an error during importing
+ if (importError instanceof LessError) throw importError;
+ else throw new(LessError)(importError, env);
+ }
+
+ if (options.yuicompress && less.mode === 'node') {
+ return require('./cssmin').compressor.cssmin(css);
+ } else if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ type: "Parse",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+
+ if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+ if (tree.colors.hasOwnProperty(k)) {
+ // detect named color
+ return new(tree.Color)(tree.colors[k].slice(1));
+ } else {
+ return new(tree.Keyword)(k);
+ }
+ }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args, index = i;
+
+ if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args, index, env.filename) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.entities.assignment) || $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ // Assignments are argument entities for calls.
+ // They are present in ie filter properties as shown below.
+ //
+ // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+ //
+
+ assignment: function () {
+ var key, value;
+ if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+ return new(tree.Assignment)(key, value);
+ }
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+
+ expect(')');
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index, env.filename);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i), important = false;
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e, i));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if ($(this.important)) {
+ important = true;
+ }
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value, cond;
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ save();
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ while (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ value = expect(this.expression, 'expected expression');
+ params.push({ name: param.name, value: value });
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ if (! $(',')) { break }
+ }
+ expect(')');
+
+ if ($(/^when/)) { // Guard
+ cond = expect(this.conditions, 'expected condition');
+ }
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset, cond);
+ } else {
+ restore();
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^\(opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ expect(')');
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c, v;
+
+ c = $(this.combinator);
+ e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+ $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+ if (! e) {
+ $('(') && (v = $(this.entities.variable)) && $(')') && (e = new(tree.Paren)(v));
+ }
+
+ if (e) { return new(tree.Element)(c, e, i) }
+
+ if (c.value && c.value.charAt(0) === '&') {
+ return new(tree.Element)(c, null, i);
+ }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === '&') {
+ match = '&';
+ i++;
+ if(input.charAt(i) === ' ') {
+ match = '& ';
+ }
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(match);
+ } else if (c === ':' && input.charAt(i + 1) === ':') {
+ i += 2;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)('::');
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path, features, index = i;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url))) {
+ features = $(this.mediaFeatures);
+ if ($(';')) {
+ return new(tree.Import)(path, imports, features, index);
+ }
+ }
+ },
+
+ mediaFeature: function () {
+ var nodes = [];
+
+ do {
+ if (e = $(this.entities.keyword)) {
+ nodes.push(e);
+ } else if ($('(')) {
+ p = $(this.property);
+ e = $(this.entity);
+ if ($(')')) {
+ if (p && e) {
+ nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+ } else if (e) {
+ nodes.push(new(tree.Paren)(e));
+ } else {
+ return null;
+ }
+ } else { return null }
+ }
+ } while (e);
+
+ if (nodes.length > 0) {
+ return new(tree.Expression)(nodes);
+ }
+ },
+
+ mediaFeatures: function () {
+ var f, features = [];
+ while (f = $(this.mediaFeature)) {
+ features.push(f);
+ if (! $(',')) { break }
+ }
+ return features.length > 0 ? features : null;
+ },
+
+ media: function () {
+ var features;
+
+ if ($(/^@media/)) {
+ features = $(this.mediaFeatures);
+
+ if (rules = $(this.block)) {
+ return new(tree.Directive)('@media', rules, features);
+ }
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types, e, nodes;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import']) || $(this.media)) {
+ return value;
+ } else if (name = $(/^@page|@keyframes/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ conditions: function () {
+ var a, b, index = i, condition;
+
+ if (a = $(this.condition)) {
+ while ($(',') && (b = $(this.condition))) {
+ condition = new(tree.Condition)('or', condition || a, b, index);
+ }
+ return condition || a;
+ }
+ },
+ condition: function () {
+ var a, b, c, op, index = i, negate = false;
+
+ if ($(/^not/)) { negate = true }
+ expect('(');
+ if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+ if (op = $(/^(?:>=|=<|[<=>])/)) {
+ if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+ c = new(tree.Condition)(op, a, b, index, negate);
+ } else {
+ error('expected expression');
+ }
+ } else {
+ c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+ }
+ expect(')');
+ return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (!/^([a-z]+:)?\//.test(path) && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, function (e) {
+ if (e && typeof(env.errback) === "function") {
+ env.errback.call(null, path, paths, callback, env);
+ } else {
+ callback.apply(null, arguments);
+ }
+ }, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fade: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a = amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ return this._math('round', n);
+ },
+ ceil: function (n) {
+ return this._math('ceil', n);
+ },
+ floor: function (n) {
+ return this._math('floor', n);
+ },
+ _math: function (fn, n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math[fn](n);
+ } else {
+ throw { type: "Argument", message: "argument must be a number" };
+ }
+ },
+ argb: function (color) {
+ return new(tree.Anonymous)(color.toARGB());
+
+ },
+ percentage: function (n) {
+ return new(tree.Dimension)(n.value * 100, '%');
+ },
+ color: function (n) {
+ if (n instanceof tree.Quoted) {
+ return new(tree.Color)(n.value.slice(1));
+ } else {
+ throw { type: "Argument", message: "argument must be a string" };
+ }
+ },
+ iscolor: function (n) {
+ return this._isa(n, tree.Color);
+ },
+ isnumber: function (n) {
+ return this._isa(n, tree.Dimension);
+ },
+ isstring: function (n) {
+ return this._isa(n, tree.Quoted);
+ },
+ iskeyword: function (n) {
+ return this._isa(n, tree.Keyword);
+ },
+ isurl: function (n) {
+ return this._isa(n, tree.URL);
+ },
+ ispixel: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+ },
+ ispercentage: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+ },
+ isem: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+ },
+ _isa: function (n, Type) {
+ return (n instanceof Type) ? tree.True : tree.False;
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+ tree.colors = {
+ 'aliceblue':'#f0f8ff',
+ 'antiquewhite':'#faebd7',
+ 'aqua':'#00ffff',
+ 'aquamarine':'#7fffd4',
+ 'azure':'#f0ffff',
+ 'beige':'#f5f5dc',
+ 'bisque':'#ffe4c4',
+ 'black':'#000000',
+ 'blanchedalmond':'#ffebcd',
+ 'blue':'#0000ff',
+ 'blueviolet':'#8a2be2',
+ 'brown':'#a52a2a',
+ 'burlywood':'#deb887',
+ 'cadetblue':'#5f9ea0',
+ 'chartreuse':'#7fff00',
+ 'chocolate':'#d2691e',
+ 'coral':'#ff7f50',
+ 'cornflowerblue':'#6495ed',
+ 'cornsilk':'#fff8dc',
+ 'crimson':'#dc143c',
+ 'cyan':'#00ffff',
+ 'darkblue':'#00008b',
+ 'darkcyan':'#008b8b',
+ 'darkgoldenrod':'#b8860b',
+ 'darkgray':'#a9a9a9',
+ 'darkgrey':'#a9a9a9',
+ 'darkgreen':'#006400',
+ 'darkkhaki':'#bdb76b',
+ 'darkmagenta':'#8b008b',
+ 'darkolivegreen':'#556b2f',
+ 'darkorange':'#ff8c00',
+ 'darkorchid':'#9932cc',
+ 'darkred':'#8b0000',
+ 'darksalmon':'#e9967a',
+ 'darkseagreen':'#8fbc8f',
+ 'darkslateblue':'#483d8b',
+ 'darkslategray':'#2f4f4f',
+ 'darkslategrey':'#2f4f4f',
+ 'darkturquoise':'#00ced1',
+ 'darkviolet':'#9400d3',
+ 'deeppink':'#ff1493',
+ 'deepskyblue':'#00bfff',
+ 'dimgray':'#696969',
+ 'dimgrey':'#696969',
+ 'dodgerblue':'#1e90ff',
+ 'firebrick':'#b22222',
+ 'floralwhite':'#fffaf0',
+ 'forestgreen':'#228b22',
+ 'fuchsia':'#ff00ff',
+ 'gainsboro':'#dcdcdc',
+ 'ghostwhite':'#f8f8ff',
+ 'gold':'#ffd700',
+ 'goldenrod':'#daa520',
+ 'gray':'#808080',
+ 'grey':'#808080',
+ 'green':'#008000',
+ 'greenyellow':'#adff2f',
+ 'honeydew':'#f0fff0',
+ 'hotpink':'#ff69b4',
+ 'indianred':'#cd5c5c',
+ 'indigo':'#4b0082',
+ 'ivory':'#fffff0',
+ 'khaki':'#f0e68c',
+ 'lavender':'#e6e6fa',
+ 'lavenderblush':'#fff0f5',
+ 'lawngreen':'#7cfc00',
+ 'lemonchiffon':'#fffacd',
+ 'lightblue':'#add8e6',
+ 'lightcoral':'#f08080',
+ 'lightcyan':'#e0ffff',
+ 'lightgoldenrodyellow':'#fafad2',
+ 'lightgray':'#d3d3d3',
+ 'lightgrey':'#d3d3d3',
+ 'lightgreen':'#90ee90',
+ 'lightpink':'#ffb6c1',
+ 'lightsalmon':'#ffa07a',
+ 'lightseagreen':'#20b2aa',
+ 'lightskyblue':'#87cefa',
+ 'lightslategray':'#778899',
+ 'lightslategrey':'#778899',
+ 'lightsteelblue':'#b0c4de',
+ 'lightyellow':'#ffffe0',
+ 'lime':'#00ff00',
+ 'limegreen':'#32cd32',
+ 'linen':'#faf0e6',
+ 'magenta':'#ff00ff',
+ 'maroon':'#800000',
+ 'mediumaquamarine':'#66cdaa',
+ 'mediumblue':'#0000cd',
+ 'mediumorchid':'#ba55d3',
+ 'mediumpurple':'#9370d8',
+ 'mediumseagreen':'#3cb371',
+ 'mediumslateblue':'#7b68ee',
+ 'mediumspringgreen':'#00fa9a',
+ 'mediumturquoise':'#48d1cc',
+ 'mediumvioletred':'#c71585',
+ 'midnightblue':'#191970',
+ 'mintcream':'#f5fffa',
+ 'mistyrose':'#ffe4e1',
+ 'moccasin':'#ffe4b5',
+ 'navajowhite':'#ffdead',
+ 'navy':'#000080',
+ 'oldlace':'#fdf5e6',
+ 'olive':'#808000',
+ 'olivedrab':'#6b8e23',
+ 'orange':'#ffa500',
+ 'orangered':'#ff4500',
+ 'orchid':'#da70d6',
+ 'palegoldenrod':'#eee8aa',
+ 'palegreen':'#98fb98',
+ 'paleturquoise':'#afeeee',
+ 'palevioletred':'#d87093',
+ 'papayawhip':'#ffefd5',
+ 'peachpuff':'#ffdab9',
+ 'peru':'#cd853f',
+ 'pink':'#ffc0cb',
+ 'plum':'#dda0dd',
+ 'powderblue':'#b0e0e6',
+ 'purple':'#800080',
+ 'red':'#ff0000',
+ 'rosybrown':'#bc8f8f',
+ 'royalblue':'#4169e1',
+ 'saddlebrown':'#8b4513',
+ 'salmon':'#fa8072',
+ 'sandybrown':'#f4a460',
+ 'seagreen':'#2e8b57',
+ 'seashell':'#fff5ee',
+ 'sienna':'#a0522d',
+ 'silver':'#c0c0c0',
+ 'skyblue':'#87ceeb',
+ 'slateblue':'#6a5acd',
+ 'slategray':'#708090',
+ 'slategrey':'#708090',
+ 'snow':'#fffafa',
+ 'springgreen':'#00ff7f',
+ 'steelblue':'#4682b4',
+ 'tan':'#d2b48c',
+ 'teal':'#008080',
+ 'thistle':'#d8bfd8',
+ 'tomato':'#ff6347',
+ 'turquoise':'#40e0d0',
+ 'violet':'#ee82ee',
+ 'wheat':'#f5deb3',
+ 'white':'#ffffff',
+ 'whitesmoke':'#f5f5f5',
+ 'yellow':'#ffff00',
+ 'yellowgreen':'#9acd32'
+ };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+ this.key = key;
+ this.value = val;
+};
+tree.Assignment.prototype = {
+ toCSS: function () {
+ return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+ this.name = name;
+ this.args = args;
+ this.index = index;
+ this.filename = filename;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ try {
+ return tree.functions[this.name].apply(tree.functions, args);
+ } catch (e) {
+ throw { type: e.type || "Runtime",
+ message: "error evaluating function `" + this.name + "`" +
+ (e.message ? ': ' + e.message : ''),
+ index: this.index, filename: this.filename };
+ }
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ },
+ toARGB: function () {
+ var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+ return '#' + argb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+ this.op = op.trim();
+ this.lvalue = l;
+ this.rvalue = r;
+ this.index = i;
+ this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+ var a = this.lvalue.eval(env),
+ b = this.rvalue.eval(env);
+
+ var i = this.index, result;
+
+ var result = (function (op) {
+ switch (op) {
+ case 'and':
+ return a && b;
+ case 'or':
+ return a || b;
+ default:
+ if (a.compare) {
+ result = a.compare(b);
+ } else if (b.compare) {
+ result = b.compare(a);
+ } else {
+ throw { type: "Type",
+ message: "Unable to perform comparison",
+ index: i };
+ }
+ switch (result) {
+ case -1: return op === '<' || op === '=<';
+ case 0: return op === '=' || op === '>=' || op === '=<';
+ case 1: return op === '>' || op === '>=';
+ }
+ }
+ })(this.op);
+ return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ },
+
+ // TODO: Perform unit conversion before comparing
+ compare: function (other) {
+ if (other instanceof tree.Dimension) {
+ if (other.value > this.value) {
+ return -1;
+ } else if (other.value < this.value) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ return -1;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value, features) {
+ this.name = name;
+ this.features = features && new(tree.Value)(features);
+
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ this.ruleset.allowImports = true;
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + features + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ this.features = this.features && this.features.eval(env);
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+
+ if (typeof(value) === 'string') {
+ this.value = value.trim();
+ } else if (value) {
+ this.value = value;
+ } else {
+ this.value = "";
+ }
+ this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+ return new(tree.Element)(this.combinator,
+ this.value.eval ? this.value.eval(env) : this.value,
+ this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + (this.value.toCSS ? this.value.toCSS(env) : this.value);
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else if (value === '& ') {
+ this.value = '& ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ '& ' : ' ',
+ ':' : ' :',
+ '::': '::',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS ? e.toCSS(env) : '';
+ }).join(' ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, index) {
+ var that = this;
+
+ this.index = index;
+ this._path = path;
+ this.features = features && new(tree.Value)(features);
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css(\?.*)?$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (e, root) {
+ if (e) { e.index = index }
+ that.root = root || new(tree.Ruleset)([], []);
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function (env) {
+ var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+ if (this.css) {
+ return "@import " + this._path.toCSS() + features + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset, features = this.features && this.features.eval(env);
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return this.features ? new(tree.Directive)('@media', ruleset.rules, this.features.value) : ruleset.rules;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value },
+ compare: function (other) {
+ if (other instanceof tree.Keyword) {
+ return other.value === this.value ? 0 : 1;
+ } else {
+ return -1;
+ }
+ }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+ this.filename = filename;
+ this.important = important;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments, this.important).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: e.index, filename: this.filename, stack: e.stack, call: this.index };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { type: 'Runtime',
+ message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index, filename: this.filename };
+ }
+ }
+ }
+ throw { type: 'Name',
+ message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index, filename: this.filename };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.condition = condition;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ evalParams: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []);
+
+ for (var i = 0, val; i < this.params.length; i++) {
+ if (this.params[i].name) {
+ if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+ } else {
+ throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ return frame;
+ },
+ eval: function (env, args, important) {
+ var frame = this.evalParams(env, args), context, _arguments = [], rules;
+
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ rules = important ?
+ this.rules.map(function (r) {
+ return new(tree.Rule)(r.name, r.value, '!important', r.index);
+ }) : this.rules.slice(0);
+
+ return new(tree.Ruleset)(null, rules).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len, frame;
+
+ if (argsLength < this.required) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+ if (this.condition && !this.condition.eval({
+ frames: [this.evalParams(env, args)].concat(env.frames)
+ })) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+ this.value = node;
+};
+tree.Paren.prototype = {
+ toCSS: function (env) {
+ return '(' + this.value.toCSS(env) + ')';
+ },
+ eval: function (env) {
+ return new(tree.Paren)(this.value.eval(env));
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return ('value' in v) ? v.value : v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+ this.inline = inline || false;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + (this.inline ? "" : ";");
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name,
+ this.value.eval(context),
+ this.important,
+ this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+ var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0));
+
+ ruleset.root = this.root;
+ ruleset.allowImports = this.allowImports;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root || ruleset.allowImports) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > rule.selectors[j].elements.length) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ this.joinSelectors(paths, context, this.selectors);
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join( env.compress ? ',' : ',\n');
+
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ },
+
+ joinSelectors: function (paths, context, selectors) {
+ for (var s = 0; s < selectors.length; s++) {
+ this.joinSelector(paths, context, selectors[s]);
+ }
+ },
+
+ joinSelector: function (paths, context, selector) {
+ var before = [], after = [], beforeElements = [],
+ afterElements = [], hasParentSelector = false, el;
+
+ for (var i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ if (el.combinator.value.charAt(0) === '&') {
+ hasParentSelector = true;
+ }
+ if (hasParentSelector) afterElements.push(el);
+ else beforeElements.push(el);
+ }
+
+ if (! hasParentSelector) {
+ afterElements = beforeElements;
+ beforeElements = [];
+ }
+
+ if (beforeElements.length > 0) {
+ before.push(new(tree.Selector)(beforeElements));
+ }
+
+ if (afterElements.length > 0) {
+ after.push(new(tree.Selector)(afterElements));
+ }
+
+ for (var c = 0; c < context.length; c++) {
+ paths.push(before.concat(context[c]).concat(after));
+ }
+ }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ var len = this.elements.length,
+ olen = other.elements.length,
+ max = Math.min(len, olen);
+
+ if (len < olen) {
+ return false;
+ } else {
+ for (var i = 0; i < max; i++) {
+ if (this.elements[i].value !== other.elements[i].value) {
+ return false;
+ }
+ }
+ }
+ return true;
+};
+tree.Selector.prototype.eval = function (env) {
+ return new(tree.Selector)(this.elements.map(function (e) {
+ return e.eval(env);
+ }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (typeof(window) !== 'undefined' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { type: 'Name',
+ message: "variable " + name + " is undefined",
+ filename: this.file,
+ index: this.index };
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+tree.jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+
+})(require('./tree'));
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:' ||
+ location.protocol === 'chrome:' ||
+ location.protocol === 'chrome-extension:' ||
+ location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (e, root, _, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (e, root, _, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+ var css = tree.toCSS();
+ var style = styles[i];
+ style.type = 'text/css';
+ if (style.styleSheet) {
+ style.styleSheet.cssText = css;
+ } else {
+ style.innerHTML = css;
+ }
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^(https?|file):/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+ var filename = href.match(/([^\/]+)$/)[1];
+
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, null, data, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type,
+ filename: filename
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ css.media = sheet.media || 'screen';
+ css.id = id;
+ document.getElementsByTagName('head')[0].appendChild(css);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? false : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol) {
+ if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+ var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+ var elem = document.createElement('div'), timer, content, error = [];
+ var filename = e.filename || href;
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p>in <a href="' + filename + '">' + filename + "</a> ";
+
+ var errorline = function (e, i, classname) {
+ if (e.extract[i]) {
+ error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
+ .replace(/\{class\}/, classname)
+ .replace(/\{content\}/, e.extract[i]));
+ }
+ };
+
+ if (e.stack) {
+ content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+ } else if (e.extract) {
+ errorline(e, 0, '');
+ errorline(e, 1, 'line');
+ errorline(e, 2, '');
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ '<ul>' + error.join('') + '</ul>';
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #dd6666;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.line {',
+ 'color: #ff0000;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless122minjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.2.min.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.2.min.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.2.2.min.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+//
+// LESS - Leaner CSS v1.2.2
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function c(b){return a.less[b.split("/")[1]]}function m(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(k)&&(new d.Parser).parse(a[b].innerHTML||"",function(c,d){var e=d.toCSS(),f=a[b];f.type="text/css",f.styleSheet?f.styleSheet.cssText=e:f.innerHTML=e})}function n(a,b){for(var c=0;c<d.sheets.length;c++)o(d.sheets[c],a,b,d.sheets.length-(c+1))}function o(b,c,e,f){var g=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/,""),j=h&&h.getItem(i),k=h&&h.getItem(i+":timestamp"),l={css:j,timestamp:k};/^(https?|file):/.test(i)||(i.charAt(0)=="/"?i=a.location.protocol+"//"+a.location.host+i:i=g.slice(0,g.lastIndexOf("/")+1)+i);var m=i.match(/([^\/]+)$/)[1];s(b.href,b.type,function(a,g){if(!e&&l&&g&&(new Date(g)).valueOf()===(new Date(l.timestamp)).valueOf())r(l.css,b),c(nul
l,null,a,b,{local:!0,remaining:f});else try{(new d.Parser({optimization:d.optimization,paths:[i.replace(/[\w\.-]+$/,"")],mime:b.type,filename:m})).parse(a,function(d,e){if(d)return w(d,i);try{c(d,e,a,b,{local:!1,lastModified:g,remaining:f}),u(document.getElementById("less-error-message:"+q(i)))}catch(d){w(d,i)}})}catch(h){w(h,i)}},function(a,b){throw new Error("Couldn't load "+b+" ("+a+")")})}function q(a){return a.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\?.*$/,"").replace(/\.[^\.\/]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function r(a,b,c){var d,e=b.href?b.href.replace(/\?.*$/,""):"",f="less:"+(b.title||q(e));(d=document.getElementById(f))===null&&(d=document.createElement("style"),d.type="text/css",d.media=b.media||"screen",d.id=f,document.getElementsByTagName("head&qu
ot;)[0].appendChild(d));if(d.styleSheet)try{d.styleSheet.cssText=a}catch(g){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(a){d.childNodes.length>0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&h&&(v("saving "+e+" to cache."),h.setItem(e,a),h.setItem(e+":timestamp",c))}function s(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var f=t(),h=g?!1:d.async;typeof f.overrideMimeType=="function"&&f.overrideMimeType("text/css"),f.open("GET",a,h),f.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),f.send(null),g?f.status===0||f.status>=200&&f.status<300?c(f.responseText):e(f.status,a):h?f.onreadystat
echange=function(){f.readyState==4&&i(f,c,e)}:i(f,c,e)}function t(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){return v("browser doesn't support AJAX."),null}}function u(a){return a&&a.parentNode.removeChild(a)}function v(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: "+a)}function w(a,b){var c="less-error-message:"+q(b),e='<li><label>{line}</label><pre class="{class}">{content}</pre></li>',f=document.createElement("div"),g,h,i=[],j=a.filename||b;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p>in <a href="'+j+'">'+j+"</a> ";var k=function(a,b,c){a.extract[b]&&i.push(e.replace(/\{line\}/,par
seInt(a.line)+(b-1)).replace(/\{class\}/,c).replace(/\{content\}/,a.extract[b]))};a.stack?h+="<br/>"+a.stack.split("\n").slice(1).join("<br/>"):a.extract&&(k(a,0,""),k(a,1,"line"),k(a,2,""),h+="on line "+a.line+", column "+(a.column+1)+":</p>"+"<ul>"+i.join("")+"</ul>"),f.innerHTML=h,r([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-mes
sage pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=setInterval(function(){document.body&&(document.getElemen
tById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}typeof define=="function"&&define.amd&&define("less",[],function(){return d}),Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d<c;d++)d in this&&a.call(b,this[d],d,this)}),Array.prototype.map||(Array.prototype.map=function(a){var b=this.length>>>0,c=new Array(b),d=arguments[1];for(var e=0;e<b;e++)e in this&&(c[e]=a.call(d,this[e],e,this));return c}),Array.prototype.filter||(Array.prototype.filter=function(a){var b=[],c=arguments[1];for(var d=0;d<this.length;d++)a.call(c,this[d])&&b.push(this[d]);return b}),Array.prototype.reduce||(Array.prototype.reduce=function(a){var b=thi
s.length>>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.length>=2)var d=arguments[1];else do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0);for(;c<b;c++)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){var b=this.length,c=arguments[1]||0;if(!b)return-1;if(c>=b)return-1;c<0&&(c+=b);for(;c<b;c++){if(!Object.prototype.hasOwnProperty.call(this,c))continue;if(a===this[c])return c}return-1}),Object.keys||(Object.keys=function(a){var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}),String.prototype.trim||(String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")});var d,f;typeof environment=="object"&&{}.toString.call(environment)==="[object Environment]"?(typeof a=="undefined"?d={}:d=a.
less={},f=d.tree={},d.mode="rhino"):typeof a=="undefined"?(d=exports,f=c("./tree"),d.mode="node"):(typeof a.less=="undefined"&&(a.less={}),d=a.less,f=a.less.tree={},d.mode="browser"),d.Parser=function(b){function t(){j=m[i],k=h,n=h}function u(){m[i]=j,h=k,n=h}function v(){h>n&&(m[i]=m[i].slice(h-n),n=h)}function w(a){var b,c,d,e,f,j,k,l;if(a instanceof Function)return a.call(o.parsers);if(typeof a=="string")b=g.charAt(h)===a?a:null,d=1,v();else{v();if(!(b=a.exec(m[i])))return null;d=b[0].length}if(b){l=h+=d,j=h+m[i].length-d;while(h<j){e=g.charCodeAt(h);if(e!==32&&e!==10&&e!==9)break;h++}return m[i]=m[i].slice(d+(h-l)),n=h,m[i].length===0&&i<m.length-1&&i++,typeof b=="string"?b:b.length===1?b[0]:b}}function x(a,b){var c=w(a);if(!!c)return c;y(b||(typeof a=="string"?"expected '"+a+"' got '"+g.charAt(h)+"'":&qu
ot;unexpected token"))}function y(a,b){throw{index:h,type:b||"Syntax",message:a}}function z(a){return typeof a=="string"?g.charAt(h)===a:a.test(m[i])?!0:!1}function A(a){return d.mode==="node"?c("path").basename(a):a.match(/[^\/]+$/)[0]}function B(a,b){return a.filename&&b.filename&&a.filename!==b.filename?o.imports.contents[A(a.filename)]:g}function C(a,b){for(var c=a,d=-1;c>=0&&b.charAt(c)!=="\n";c--)d++;return{line:typeof a=="number"?(b.slice(0,a).match(/\n/g)||"").length:null,column:d}}function D(a,b){var c=B(a,b),d=C(a.index,c),e=d.line,f=d.column,g=c.split("\n");this.type=a.type||"Syntax",this.message=a.message,this.filename=a.filename||b.filename,this.index=a.index,this.line=typeof e=="number"?e+1:null,this.callLine=a.call&&C(a.call,c)+1,this.callExtract=g[C(a.call,c)],this.stack=a.stack,this.column=f,this.extract=[g[e-1],g[e],g[e+1]]}var
g,h,i,j,k,l,m,n,o,q=this,r=function(){},s=this.imports={paths:b&&b.paths||[],queue:[],files:{},contents:{},mime:b&&b.mime,error:null,push:function(a,c){var e=this;this.queue.push(a),d.Parser.importer(a,this.paths,function(b,d,f){e.queue.splice(e.queue.indexOf(a),1),e.files[a]=d,e.contents[a]=f,b&&!e.error&&(e.error=b),c(b,d),e.queue.length===0&&r()},b)}};return this.env=b=b||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.filename=this.env.filename||null,o={imports:s,parse:function(a,e){var j,k,p,q,s,t,u=[],v,x=null;h=i=n=l=0,g=a.replace(/\r\n/g,"\n"),m=function(a){var c=0,d=/[^"'`\{\}\/\(\)\\]+/g,e=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,f=/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`\\\r\n]|\\.)*)`/g,h=0,i,j=a[0],k;for(var l=0,m,n;l<g.length;l++){d.lastIndex=l,(i=d.exec(g))&&i.index===l&&(l+=i[0].length,j.push(i[0])),m=g.charAt(l),e.lastInd
ex=f.lastIndex=l,(i=f.exec(g))&&i.index===l&&(l+=i[0].length,j.push(i[0]),m=g.charAt(l)),!k&&m==="/"&&(n=g.charAt(l+1),(n==="/"||n==="*")&&(i=e.exec(g))&&i.index===l&&(l+=i[0].length,j.push(i[0]),m=g.charAt(l)));switch(m){case"{":if(!k){h++,j.push(m);break};case"}":if(!k){h--,j.push(m),a[++c]=j=[];break};case"(":if(!k){k=!0,j.push(m);break};case")":if(k){k=!1,j.push(m);break};default:j.push(m)}}return h>0&&(x=new D({index:l,type:"Parse",message:"missing closing `}`",filename:b.filename},b)),a.map(function(a){return a.join("")})}([[]]);if(x)return e(x);try{j=new f.Ruleset([],w(this.parsers.primary)),j.root=!0}catch(y){return e(new D(y,b))}j.toCSS=function(a){var e,g,h;return function(e,g){var h=[],i;e=e||{},typeof g=="object"&&!Array.isArray(g)&&(g=Object.keys(g).map(function(a){var b=g[a];retu
rn b instanceof f.Value||(b instanceof f.Expression||(b=new f.Expression([b])),b=new f.Value([b])),new f.Rule("@"+a,b,!1,0)}),h=[new f.Ruleset(null,g)]);try{var j=a.call(this,{frames:h}).toCSS([],{compress:e.compress||!1})}catch(k){throw new D(k,b)}if(i=o.imports.error)throw i instanceof D?i:new D(i,b);return e.yuicompress&&d.mode==="node"?c("./cssmin").compressor.cssmin(j):e.compress?j.replace(/(\s)+/g,"$1"):j}}(j.eval);if(h<g.length-1){h=l,t=g.split("\n"),s=(g.slice(0,h).match(/\n/g)||"").length+1;for(var z=h,A=-1;z>=0&&g.charAt(z)!=="\n";z--)A++;x={type:"Parse",message:"Syntax Error on line "+s,index:h,filename:b.filename,line:s,column:A,extract:[t[s-2],t[s-1],t[s]]}}this.imports.queue.length>0?r=function(){e(x,j)}:e(x,j)},parsers:{primary:function(){var a,b=[];while((a=w(this.mixin.definition)||w(this.rule)||w(this.ruleset)||w(this.mixin.call)||w(this.comment)||w(th
is.directive))||w(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(g.charAt(h)!=="/")return;if(g.charAt(h+1)==="/")return new f.Comment(w(/^\/\/.*/),!0);if(a=w(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new f.Comment(a)},entities:{quoted:function(){var a,b=h,c;g.charAt(b)==="~"&&(b++,c=!0);if(g.charAt(b)!=='"'&&g.charAt(b)!=="'")return;c&&w("~");if(a=w(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new f.Quoted(a[0],a[1]||a[2],c)},keyword:function(){var a;if(a=w(/^[_A-Za-z-][_A-Za-z0-9-]*/))return f.colors.hasOwnProperty(a)?new f.Color(f.colors[a].slice(1)):new f.Keyword(a)},call:function(){var a,c,d=h;if(!(a=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(m[i])))return;a=a[1].toLowerCase();if(a==="url")return null;h+=a.length;if(a==="alpha")return w(this.alpha);w("("),c=w(this.entities.arguments);if(!w(")"))return;if(a)return ne
w f.Call(a,c,d,b.filename)},arguments:function(){var a=[],b;while(b=w(this.entities.assignment)||w(this.expression)){a.push(b);if(!w(","))break}return a},literal:function(){return w(this.entities.dimension)||w(this.entities.color)||w(this.entities.quoted)},assignment:function(){var a,b;if((a=w(/^\w+(?=\s?=)/i))&&w("=")&&(b=w(this.entity)))return new f.Assignment(a,b)},url:function(){var a;if(g.charAt(h)!=="u"||!w(/^url\(/))return;return a=w(this.entities.quoted)||w(this.entities.variable)||w(this.entities.dataURI)||w(/^[-\w%@$\/.&=:;#+?~]+/)||"",x(")"),new f.URL(a.value||a.data||a instanceof f.Variable?a:new f.Anonymous(a),s.paths)},dataURI:function(){var a;if(w(/^data:/)){a={},a.mime=w(/^[^\/]+\/[^,;)]+/)||"",a.charset=w(/^;\s*charset=[^,;)]+/)||"",a.base64=w(/^;\s*base64/)||"",a.data=w(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var a,c=h;if(g.charAt(h)==="@"&am
p;&(a=w(/^@@?[\w-]+/)))return new f.Variable(a,c,b.filename)},color:function(){var a;if(g.charAt(h)==="#"&&(a=w(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new f.Color(a[1])},dimension:function(){var a,b=g.charCodeAt(h);if(b>57||b<45||b===47)return;if(a=w(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new f.Dimension(a[1],a[2])},javascript:function(){var a,b=h,c;g.charAt(b)==="~"&&(b++,c=!0);if(g.charAt(b)!=="`")return;c&&w("~");if(a=w(/^`([^`]*)`/))return new f.JavaScript(a[1],h,c)}},variable:function(){var a;if(g.charAt(h)==="@"&&(a=w(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!z(/^[@\w.%-]+\/[@\w.-]+/))return;if((a=w(this.entity))&&w("/")&&(b=w(this.entity)))return new f.Shorthand(a,b)},mixin:{call:function(){var a=[],c,d,e,i=h,j=g.charAt(h),k=!1;if(j!=="."&&j!=="#")return;while(c=w
(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))a.push(new f.Element(d,c,h)),d=w(">");w("(")&&(e=w(this.entities.arguments))&&w(")"),w(this.important)&&(k=!0);if(a.length>0&&(w(";")||z("}")))return new f.mixin.Call(a,e,i,b.filename,k)},definition:function(){var a,b=[],c,d,e,i,j;if(g.charAt(h)!=="."&&g.charAt(h)!=="#"||z(/^[^{]*(;|})/))return;t();if(c=w(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=c[1];while(e=w(this.entities.variable)||w(this.entities.literal)||w(this.entities.keyword)){e instanceof f.Variable?w(":")?(i=x(this.expression,"expected expression"),b.push({name:e.name,value:i})):b.push({name:e.name}):b.push({value:e});if(!w(","))break}x(")"),w(/^when/)&&(j=x(this.conditions,"expected condition")),d=w(this.block);if(d)return new f.mixin.Definition(a,b,d,j);u()}}},entity
:function(){return w(this.entities.literal)||w(this.entities.variable)||w(this.entities.url)||w(this.entities.call)||w(this.entities.keyword)||w(this.entities.javascript)||w(this.comment)},end:function(){return w(";")||z("}")},alpha:function(){var a;if(!w(/^\(opacity=/i))return;if(a=w(/^\d+/)||w(this.entities.variable))return x(")"),new f.Alpha(a)},element:function(){var a,b,c,d;c=w(this.combinator),a=w(/^(?:\d+\.\d+|\d+)%/)||w(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||w("*")||w(this.attribute)||w(/^\([^)@]+\)/),a||w("(")&&(d=w(this.entities.variable))&&w(")")&&(a=new f.Paren(d));if(a)return new f.Element(c,a,h);if(c.value&&c.value.charAt(0)==="&")return new f.Element(c,null,h)},combinator:function(){var a,b=g.charAt(h);if(b===">"||b==="+"||b==="~"){h++;while(g.charAt(h)===" ")h++;return new f.Combinator(b)}if(b=
=="&"){a="&",h++,g.charAt(h)===" "&&(a="& ");while(g.charAt(h)===" ")h++;return new f.Combinator(a)}if(b===":"&&g.charAt(h+1)===":"){h+=2;while(g.charAt(h)===" ")h++;return new f.Combinator("::")}return g.charAt(h-1)===" "?new f.Combinator(" "):new f.Combinator(null)},selector:function(){var a,b,c=[],d,e;while(b=w(this.element)){d=g.charAt(h),c.push(b);if(d==="{"||d==="}"||d===";"||d===",")break}if(c.length>0)return new f.Selector(c)},tag:function(){return w(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||w("*")},attribute:function(){var a="",b,c,d;if(!w("["))return;if(b=w(/^[a-zA-Z-]+/)||w(this.entities.quoted))(d=w(/^[|~*$^]?=/))&&(c=w(this.entities.quoted)||w(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!w("]"))return;if(a)return"["+a+"]
"},block:function(){var a;if(w("{")&&(a=w(this.primary))&&w("}"))return a},ruleset:function(){var a=[],b,c,d;t();while(b=w(this.selector)){a.push(b),w(this.comment);if(!w(","))break;w(this.comment)}if(a.length>0&&(c=w(this.block)))return new f.Ruleset(a,c);l=h,u()},rule:function(){var a,b,c=g.charAt(h),d,e;t();if(c==="."||c==="#"||c==="&")return;if(a=w(this.variable)||w(this.property)){a.charAt(0)!="@"&&(e=/^([^@+\/'"*`(;{}-]*);/.exec(m[i]))?(h+=e[0].length-1,b=new f.Anonymous(e[1])):a==="font"?b=w(this.font):b=w(this.value),d=w(this.important);if(b&&w(this.end))return new f.Rule(a,b,d,k);l=h,u()}},"import":function(){var a,b,c=h;if(w(/^@import\s+/)&&(a=w(this.entities.quoted)||w(this.entities.url))){b=w(this.mediaFeatures);if(w(";"))return new f.Import(a,s,b,c)}},mediaFeature:function(){var a=[];do if(e=w(this.entities.
keyword))a.push(e);else if(w("(")){p=w(this.property),e=w(this.entity);if(!w(")"))return null;if(p&&e)a.push(new f.Paren(new f.Rule(p,e,null,h,!0)));else{if(!e)return null;a.push(new f.Paren(e))}}while(e);if(a.length>0)return new f.Expression(a)},mediaFeatures:function(){var a,b=[];while(a=w(this.mediaFeature)){b.push(a);if(!w(","))break}return b.length>0?b:null},media:function(){var a;if(w(/^@media/)){a=w(this.mediaFeatures);if(rules=w(this.block))return new f.Directive("@media",rules,a)}},directive:function(){var a,b,c,d,e,i;if(g.charAt(h)!=="@")return;if(b=w(this["import"])||w(this.media))return b;if(a=w(/^@page|@keyframes/)||w(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)){d=(w(/^[^{]+/)||"").trim();if(c=w(this.block))return new f.Directive(a+" "+d,c)}else if(a=w(/^@[-a-z]+/))if(a==="@font-face"){if(c=w(this.block))return new f.Directive(a,c)}else if((b=w(this.entity))&&w
(";"))return new f.Directive(a,b)},font:function(){var a=[],b=[],c,d,e,g;while(g=w(this.shorthand)||w(this.entity))b.push(g);a.push(new f.Expression(b));if(w(","))while(g=w(this.expression)){a.push(g);if(!w(","))break}return new f.Value(a)},value:function(){var a,b=[],c;while(a=w(this.expression)){b.push(a);if(!w(","))break}if(b.length>0)return new f.Value(b)},important:function(){if(g.charAt(h)==="!")return w(/^! *important/)},sub:function(){var a;if(w("(")&&(a=w(this.expression))&&w(")"))return a},multiplication:function(){var a,b,c,d;if(a=w(this.operand)){while(!z(/^\/\*/)&&(c=w("/")||w("*"))&&(b=w(this.operand)))d=new f.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,b,c,d;if(a=w(this.multiplication)){while((c=w(/^[-+]\s+/)||g.charAt(h-1)!=" "&&(w("+")||w("-")))&&(b=w(this.multiplication)))d=new f
.Operation(c,[d||a,b]);return d||a}},conditions:function(){var a,b,c=h,d;if(a=w(this.condition)){while(w(",")&&(b=w(this.condition)))d=new f.Condition("or",d||a,b,c);return d||a}},condition:function(){var a,b,c,d,e=h,g=!1;w(/^not/)&&(g=!0),x("(");if(a=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))return(d=w(/^(?:>=|=<|[<=>])/))?(b=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))?c=new f.Condition(d,a,b,e,g):y("expected expression"):c=new f.Condition("=",a,new f.Keyword("true"),e,g),x(")"),w(/^and/)?new f.Condition("and",c,w(this.condition)):c},operand:function(){var a,b=g.charAt(h+1);g.charAt(h)==="-"&&(b==="@"||b==="(")&&(a=w("-"));var c=w(this.sub)||w(this.entities.dimension)||w(this.entities.color)||w(this.entities.variable)||w(this.entities.call);return a?new f.Operation("
;*",[new f.Dimension(-1),c]):c},expression:function(){var a,b,c=[],d;while(a=w(this.addition)||w(this.entity))c.push(a);if(c.length>0)return new f.Expression(c)},property:function(){var a;if(a=w(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}};if(d.mode==="browser"||d.mode==="rhino")d.Parser.importer=function(a,b,c,d){!/^([a-z]+:)?\//.test(a)&&b.length>0&&(a=b[0]+a),o({href:a,title:a,type:d.mime},function(e){e&&typeof d.errback=="function"?d.errback.call(null,a,b,c,d):c.apply(null,arguments)},!0)};(function(a){function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function d(a){return Math.min(1,Math.max(0,a))}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b
,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){return a=a<0?a+1:a>1?a-1:a,a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(Math.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();return e.s+=c.value/100,e.s=d(e.s),b(e)},desaturate:function(a,c){var e=a.toHSL();return e.s-=c.value/100,e.s=d(e.s),b(e)},lighten:function(a,c){var e=a.toHSL();return e.l+=c.value/100,e.l=d(e.l),b(e)},darken:function(a,c){var e=a.toHSL();return e.l-=c.value/100,e.l
=d(e.l),b(e)},fadein:function(a,c){var e=a.toHSL();return e.a+=c.value/100,e.a=d(e.a),b(e)},fadeout:function(a,c){var e=a.toHSL();return e.a-=c.value/100,e.a=d(e.a),b(e)},fade:function(a,c){var e=a.toHSL();return e.a=c.value/100,e.a=d(e.a),b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;return d.h=e<0?360+e:e,b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array
.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e<c.length;e++)d=d.replace(/%[sda]/i,function(a){var b=a.match(/s/i)?c[e].value:c[e].toCSS();return a.match(/[A-Z]$/)?encodeURIComponent(b):b});return d=d.replace(/%%/g,"%"),new a.Quoted('"'+d+'"',d)},round:function(a){return this._math("round",a)},ceil:function(a){return this._math("ceil",a)},floor:function(a){return this._math("floor",a)},_math:function(b,d){if(d instanceof a.Dimension)return new a.Dimension(Math[b](c(d)),d.unit);if(typeof d=="number")return Math[b](d);throw{type:"Argument",message:"argument must be a number"}},argb:function(b){return new a.Anonymous(b.toARGB())},percentage:function(b){return new a.Dimension(b.value*100,"%")},color:function(b){if(b instanceof a.Quoted)return new a.Color(b.value.slice(1));throw{type:"Argument",message:"argument must be a string"}},iscolor:function(b){return this._i
sa(b,a.Color)},isnumber:function(b){return this._isa(b,a.Dimension)},isstring:function(b){return this._isa(b,a.Quoted)},iskeyword:function(b){return this._isa(b,a.Keyword)},isurl:function(b){return this._isa(b,a.URL)},ispixel:function(b){return b instanceof a.Dimension&&b.unit==="px"?a.True:a.False},ispercentage:function(b){return b instanceof a.Dimension&&b.unit==="%"?a.True:a.False},isem:function(b){return b instanceof a.Dimension&&b.unit==="em"?a.True:a.False},_isa:function(b,c){return b instanceof c?a.True:a.False}}})(c("./tree")),function(a){a.colors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887"
,cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"
#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#7
78899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#
afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00&
quot;,yellowgreen:"#9acd32"}}(c("./tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(a){return this.value.eval&&(this.value=this.value.eval(a)),this}}}(c("../tree")),function(a){a.Anonymous=function(a){this.value=a.value||a},a.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Assignment=function(a,b){this.key=a,this.value=b},a.Assignment.prototype={toCSS:function(){return this.key+"="+(this.value.toCSS?this.value.toCSS():this.value)},eval:function(a){return this.value.eval&&(this.value=this.value.eval(a)),this}}}(c("../tree")),function(a){a.Call=function(a,b,c,d){this.name=a,this.args=b,this.index=c,this.filename=d},a.Call.prototype={eval:function(b){var c=this.args.map(function(a){return a.eval
(b)});if(!(this.name in a.functions))return new a.Anonymous(this.name+"("+c.map(function(a){return a.toCSS()}).join(", ")+")");try{return a.functions[this.name].apply(a.functions,c)}catch(d){throw{type:d.type||"Runtime",message:"error evaluating function `"+this.name+"`"+(d.message?": "+d.message:""),index:this.index,filename:this.filename}}},toCSS:function(a){return this.eval(a).toCSS()}}}(c("../tree")),function(a){a.Color=function(a,b){Array.isArray(a)?this.rgb=a:a.length==6?this.rgb=a.match(/.{2}/g).map(function(a){return parseInt(a,16)}):this.rgb=a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha=typeof b=="number"?b:1},a.Color.prototype={eval:function(){return this},toCSS:function(){return this.alpha<1?"rgba("+this.rgb.map(function(a){return Math.round(a)}).concat(this.alpha).join(", ")+")":"#"+this.rgb.map(functi
on(a){return a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);switch(e){case a:g=(b-c)/j+(b<c?6:0);break;case b:g=(c-a)/j+2;break;case c:g=(a-b)/j+4}g/=6}return{h:g*360,s:h,l:i,a:d}},toARGB:function(){var a=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+a.map(function(a){return a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")}}}(c("../tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?""
;:this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Condition=function(a,b,c,d,e){this.op=a.trim(),this.lvalue=b,this.rvalue=c,this.index=d,this.negate=e},a.Condition.prototype.eval=function(a){var b=this.lvalue.eval(a),c=this.rvalue.eval(a),d=this.index,e,e=function(a){switch(a){case"and":return b&&c;case"or":return b||c;default:if(b.compare)e=b.compare(c);else{if(!c.compare)throw{type:"Type",message:"Unable to perform comparison",index:d};e=c.compare(b)}switch(e){case-1:return a==="<"||a==="=<";case 0:return a==="="||a===">="||a==="=<";case 1:return a===">"||a===">="}}}(this.op);return this.negate?!e:e}}(c("../tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.val
ue,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)},compare:function(b){return b instanceof a.Dimension?b.value>this.value?-1:b.value<this.value?1:0:-1}}}(c("../tree")),function(a){a.Directive=function(b,c,d){this.name=b,this.features=d&&new a.Value(d),Array.isArray(c)?(this.ruleset=new a.Ruleset([],c),this.ruleset.allowImports=!0):this.value=c},a.Directive.prototype={toCSS:function(a,b){var c=this.features?" "+this.features.toCSS(b):"";return this.ruleset?(this.ruleset.root=!0,this.name+c+(b.compress?"{":" {\n ")+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n ")+(b.compress?"}":"\n}\n")):this.name+" "+this.value.toCSS()+";\n"},eval:function(a){return this.features=this.features&&this.features.eval(a),a.frames.unshift(this),this.ruleset=this.rul
eset&&this.ruleset.eval(a),a.frames.shift(),this},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(c("../tree")),function(a){a.Element=function(b,c,d){this.combinator=b instanceof a.Combinator?b:new a.Combinator(b),typeof c=="string"?this.value=c.trim():c?this.value=c:this.value="",this.index=d},a.Element.prototype.eval=function(b){return new a.Element(this.combinator,this.value.eval?this.value.eval(b):this.value,this.index)},a.Element.prototype.toCSS=function(a){return this.combinator.toCSS(a||{})+(this.value.toCSS?this.value.toCSS(a):this.value)},a.Combinator=function(a){a===" "?this.value=" ":a==="& "?this.value="& ":this.value=a?a.trim():""},a.Combinator.prototype.toCSS=function(a){return{""
;:""," ":" ","&":"","& ":" ",":":" :","::":"::","+":a.compress?"+":" + ","~":a.compress?"~":" ~ ",">":a.compress?">":" > "}[this.value]}}(c("../tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS?b.toCSS(a):""}).join(" ")}}}(c("../tree")),function(a){a.Import=function(b,c,d,e){var f=this;this.index=e,this._path=b,this.features=d&&new a.Value(d),b instanceof a.Quoted?this.path=/\.(le?|c)ss(\?.*)?$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value|
|b.value,this.css=/css(\?.*)?$/.test(this.path),this.css||c.push(this.path,function(b,c){b&&(b.index=e),f.root=c||new a.Ruleset([],[])})},a.Import.prototype={toCSS:function(a){var b=this.features?" "+this.features.toCSS(a):"";return this.css?"@import "+this._path.toCSS()+b+";\n":""},eval:function(b){var c,d=this.features&&this.features.eval(b);if(this.css)return this;c=new a.Ruleset([],this.root.rules.slice(0));for(var e=0;e<c.rules.length;e++)c.rules[e]instanceof a.Import&&Array.prototype.splice.apply(c.rules,[e,1].concat(c.rules[e].eval(b)));return this.features?new
+a.Directive("@media",c.rules,this.features.value):c.rules}}}(c("../tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify((new a.Variable("@"+e,d.index)).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: `"+f+"`",index:this.index}}for(var h in b.frames[0].variables())e[h.slice(1)]={value:b.frames[0].variables()[h].value,toJS:function(){return this.value.eval(b).toCSS()}};try{c=f.call(e)}catch(g){throw{message:"JavaScript evaluation error: '"+g.name+": "+g.message+"'",index:this.index}}return typeof c=="string"?new a.Quoted('"'+c+'"',c,this.escaped,this.index):Array.isArray(c)?new a.Anonymous(c.join(", ")):new a.Anonymous(c)}}}(c(".
./tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value},compare:function(b){return b instanceof a.Keyword?b.value===this.value?0:1:-1}},a.True=new a.Keyword("true"),a.False=new a.Keyword("false")}(c("../tree")),function(a){a.mixin={},a.mixin.Call=function(b,c,d,e,f){this.selector=new a.Selector(b),this.arguments=c,this.index=d,this.filename=e,this.important=f},a.mixin.Call.prototype={eval:function(a){var b,c,d=[],e=!1;for(var f=0;f<a.frames.length;f++)if((b=a.frames[f].find(this.selector)).length>0){c=this.arguments&&this.arguments.map(function(b){return b.eval(a)});for(var g=0;g<b.length;g++)if(b[g].match(c,a))try{Array.prototype.push.apply(d,b[g].eval(a,this.arguments,this.important).rules),e=!0}catch(h){throw{message:h.message,index:h.index,filename:this.filename,stack:h.stack,call:this.index}}if(e)return d;throw{type:"Runtime",mess
age:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(a){return a.toCSS()}).join(", ")+")`",index:this.index,filename:this.filename}}throw{type:"Name",message:this.selector.toCSS().trim()+" is undefined",index:this.index,filename:this.filename}}},a.mixin.Definition=function(b,c,d,e){this.name=b,this.selectors=[new a.Selector([new a.Element(null,b)])],this.params=c,this.condition=e,this.arity=c.length,this.rules=d,this._lookups={},this.required=c.reduce(function(a,b){return!b.name||b.name&&!b.value?a+1:a},0),this.parent=a.Ruleset.prototype,this.frames=[]},a.mixin.Definition.prototype={toCSS:function(){return""},variable:function(a){return this.parent.variable.call(this,a)},variables:function(){return this.parent.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},
evalParams:function(b,c){var d=new a.Ruleset(null,[]);for(var e=0,f;e<this.params.length;e++)if(this.params[e].name){if(!(f=c&&c[e]||this.params[e].value))throw{type:"Runtime",message:"wrong number of arguments for "+this.name+" ("+c.length+" for "+this.arity+")"};d.rules.unshift(new a.Rule(this.params[e].name,f.eval(b)))}return d},eval:function(b,c,d){var e=this.evalParams(b,c),f,g=[],h;for(var i=0;i<Math.max(this.params.length,c&&c.length);i++)g.push(c[i]||this.params[i].value);return e.rules.unshift(new a.Rule("@arguments",(new a.Expression(g)).eval(b))),h=d?this.rules.map(function(b){return new a.Rule(b.name,b.value,"!important",b.index)}):this.rules.slice(0),(new a.Ruleset(null,h)).eval({frames:[this,e].concat(this.frames,b.frames)})},match:function(a,b){var c=a&&a.length||0,d,e;if(c<this.required)return!1;if(this.required>0&&c>this.params.length)return!1;if(this
.condition&&!this.condition.eval({frames:[this.evalParams(b,a)].concat(b.frames)}))return!1;d=Math.min(c,this.arity);for(var f=0;f<d;f++)if(!this.params[f].name&&a[f].eval(b).toCSS()!=this.params[f].value.eval(b).toCSS())return!1;return!0}}}(c("../tree")),function(a){a.Operation=function(a,b){this.op=a.trim(),this.operands=b},a.Operation.prototype.eval=function(b){var c=this.operands[0].eval(b),d=this.operands[1].eval(b),e;if(c instanceof a.Dimension&&d instanceof a.Color){if(this.op!=="*"&&this.op!=="+")throw{name:"OperationError",message:"Can't substract or divide a color from a number"};e=d,d=c,c=e}return c.operate(this.op,d)},a.operate=function(a,b,c){switch(a){case"+":return b+c;case"-":return b-c;case"*":return b*c;case"/":return b/c}}}(c("../tree")),function(a){a.Paren=function(a){this.value=a},a.Paren.prototype={toCSS:function(a){return"
("+this.value.toCSS(a)+")"},eval:function(b){return new a.Paren(this.value.eval(b))}}}(c("../tree")),function(a){a.Quoted=function(a,b,c,d){this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d},a.Quoted.prototype={toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(b){var c=this,d=this.value.replace(/`([^`]+)`/g,function(d,e){return(new a.JavaScript(e,c.index,!0)).eval(b).value}).replace(/@\{([\w-]+)\}/g,function(d,e){var f=(new a.Variable("@"+e,c.index)).eval(b);return"value"in f?f.value:f.toCSS()});return new a.Quoted(this.quote+d+this.quote,d,this.escaped,this.index)}}}(c("../tree")),function(a){a.Rule=function(b,c,d,e,f){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.index=e,this.inline=f||!1,b.charAt(0)==="@"?this.variable=!0:this.variable=!1},a.Rule.prototype.toCSS=functio
n(a){return this.variable?"":this.name+(a.compress?":":": ")+this.value.toCSS(a)+this.important+(this.inline?"":";")},a.Rule.prototype.eval=function(b){return new a.Rule(this.name,this.value.eval(b),this.important,this.index,this.inline)},a.Shorthand=function(a,b){this.a=a,this.b=b},a.Shorthand.prototype={toCSS:function(a){return this.a.toCSS(a)+"/"+this.b.toCSS(a)},eval:function(){return this}}}(c("../tree")),function(a){a.Ruleset=function(a,b){this.selectors=a,this.rules=b,this._lookups={}},a.Ruleset.prototype={eval:function(b){var c=this.selectors&&this.selectors.map(function(a){return a.eval(b)}),d=new a.Ruleset(c,this.rules.slice(0));d.root=this.root,d.allowImports=this.allowImports,b.frames.unshift(d);if(d.root||d.allowImports)for(var e=0;e<d.rules.length;e++)d.rules[e]instanceof a.Import&&Array.prototype.splice.apply(d.rules,[e,1].concat(d.rules[e].eval(b)));for(var e=0;e<d.rules.lengt
h;e++)d.rules[e]instanceof a.mixin.Definition&&(d.rules[e].frames=b.frames.slice(0));for(var e=0;e<d.rules.length;e++)d.rules[e]instanceof a.mixin.Call&&Array.prototype.splice.apply(d.rules,[e,1].concat(d.rules[e].eval(b)));for(var e=0,f;e<d.rules.length;e++)f=d.rules[e],f instanceof a.mixin.Definition||(d.rules[e]=f.eval?f.eval(b):f);return b.frames.shift(),d},match:function(a){return!a||a.length===0},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(b,c){return c instanceof a.Rule&&c.variable===!0&&(b[c.name]=c),b},{})},variable:function(a){return this.variables()[a]},rulesets:function(){return this._rulesets?this._rulesets:this._rulesets=this.rules.filter(function(b){return b instanceof a.Ruleset||b instanceof a.mixin.Definition})},find:function(b,c){c=c||this;var d=[],e,f,g=b.toCSS();return g in this._lookups?this._lookups[g]:(this.rulesets().forEach(function(e){if(e!==c)for(var g=0;g<e
.selectors.length;g++)if(f=b.match(e.selectors[g])){b.elements.length>e.selectors[g].elements.length?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}}),this._lookups[g]=d)},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;this.root||(b.length===0?g=this.selectors.map(function(a){return[a]}):this.joinSelectors(g,b,this.selectors));for(var j=0;j<this.rules.length;j++)i=this.rules[j],i.rules||i instanceof a.Directive?f.push(i.toCSS(g,c)):i instanceof a.Comment?i.silent||(this.root?f.push(i.toCSS(c)):e.push(i.toCSS(c))):i.toCSS&&!i.variable?e.push(i.toCSS(c)):i.value&&!i.variable&&e.push(i.value.toString());return f=f.join(""),this.root?d.push(e.join(c.compress?"":"\n")):e.length>0&&(h=g.map(function(a){return a.map(function(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":",\n"),d.push(h,(c.compress?"{":" {\n ")
+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f),d.join("")+(c.compress?"\n":"")},joinSelectors:function(a,b,c){for(var d=0;d<c.length;d++)this.joinSelector(a,b,c[d])},joinSelector:function(b,c,d){var e=[],f=[],g=[],h=[],i=!1,j;for(var k=0;k<d.elements.length;k++)j=d.elements[k],j.combinator.value.charAt(0)==="&"&&(i=!0),i?h.push(j):g.push(j);i||(h=g,g=[]),g.length>0&&e.push(new a.Selector(g)),h.length>0&&f.push(new a.Selector(h));for(var l=0;l<c.length;l++)b.push(e.concat(c[l]).concat(f))}}}(c("../tree")),function(a){a.Selector=function(a){this.elements=a,this.elements[0].combinator.value===""&&(this.elements[0].combinator.value=" ")},a.Selector.prototype.match=function(a){var b=this.elements.length,c=a.elements.length,d=Math.min(b,c);if(b<c)return!1;for(var e=0;e<d;e++)if(this.elements[e].value!==a.
elements[e].value)return!1;return!0},a.Selector.prototype.eval=function(b){return new a.Selector(this.elements.map(function(a){return a.eval(b)}))},a.Selector.prototype.toCSS=function(a){return this._css?this._css:this._css=this.elements.map(function(b){return typeof b=="string"?" "+b.trim():b.toCSS(a)}).join("")}}(c("../tree")),function(b){b.URL=function(b,c){b.data?this.attrs=b:(typeof a!="undefined"&&!/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(b.value)&&c.length>0&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("../tree")),function(a){a.Value=function(a){this.value=a
,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("../tree")),function(a){a.Variable=function(a,b,c){this.name=a,this.index=b,this.file=c},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{type:"Name",message:"variable "+e+" is undefined",filename:this.file,index:this.index}}}}(c("../tree")),function(a){a.find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null},a.jsify=function(a){return Array.isArray(a.value)&&a.value.length>1?"["+a.valu
e.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)}}(c("./tree"));var g=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||g?"development":"production"),d.async=!1,d.poll=d.poll||(g?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&n(function(a,b,c,d,e){b&&r(b.toCSS(),d,e.lastModified)})},d.poll)):d.optimization=3;var h;try{h=typeof a.localStorage=="undefined"?null:a.localStorage}catch(i){h=null}var j=document.getEle
mentsByTagName("link"),k=/^text\/(x-)?less$/;d.sheets=[];for(var l=0;l<j.length;l++)(j[l].rel==="stylesheet/less"||j[l].rel.match(/stylesheet/)&&j[l].type.match(k))&&d.sheets.push(j[l]);d.refresh=function(a){var b,c;b=c=new Date,n(function(a,d,e,f,g){g.local?v("loading "+f.href+" from cache."):(v("parsed "+f.href+" successfully."),r(d.toCSS(),f,g.lastModified)),v("css for "+f.href+" generated in "+(new Date-c)+"ms"),g.remaining===0&&v("css generated in "+(new Date-b)+"ms"),c=new Date},a),m()},d.refreshStyles=m,d.refresh(d.env==="development")})(window);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless130js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3478 @@
</span><ins>+//
+// LESS - Leaner CSS v1.3.0
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
+// amd.js
+//
+// Define Less as an AMD module.
+if (typeof define === "function" && define.amd) {
+ define("less", [], function () { return less; } );
+}
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+ // Rhino
+ // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+ if (typeof(window) === 'undefined') { less = {} }
+ else { less = window.less = {} }
+ tree = less.tree = {};
+ less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+ // Node.js
+ less = exports,
+ tree = require('./tree');
+ less.mode = 'node';
+} else {
+ // Browser
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+ less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ contents: {}, // Holds the imported file contents
+ mime: env && env.mime, // MIME type of .less files
+ error: null, // Error in parsing/evaluating an import
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (e, root, contents) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+ that.contents[path] = contents;
+
+ if (e && !that.error) { that.error = e }
+ callback(e, root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ function expect(arg, msg) {
+ var result = $(arg);
+ if (! result) {
+ error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+ : "unexpected token"));
+ } else {
+ return result;
+ }
+ }
+
+ function error(msg, type) {
+ throw { index: i, type: type || 'Syntax', message: msg };
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ function basename(pathname) {
+ if (less.mode === 'node') {
+ return require('path').basename(pathname);
+ } else {
+ return pathname.match(/[^\/]+$/)[0];
+ }
+ }
+
+ function getInput(e, env) {
+ if (e.filename && env.filename && (e.filename !== env.filename)) {
+ return parser.imports.contents[basename(e.filename)];
+ } else {
+ return input;
+ }
+ }
+
+ function getLocation(index, input) {
+ for (var n = index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ return { line: typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+ column: column };
+ }
+
+ function LessError(e, env) {
+ var input = getInput(e, env),
+ loc = getLocation(e.index, input),
+ line = loc.line,
+ col = loc.column,
+ lines = input.split('\n');
+
+ this.type = e.type || 'Syntax';
+ this.message = e.message;
+ this.filename = e.filename || env.filename;
+ this.index = e.index;
+ this.line = typeof(line) === 'number' ? line + 1 : null;
+ this.callLine = e.call && (getLocation(e.call, input).line + 1);
+ this.callExtract = lines[getLocation(e.call, input).line];
+ this.stack = e.stack;
+ this.column = col;
+ this.extract = [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ];
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)\\]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`\\\r\n]|\\.)*)`/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = string.lastIndex = i;
+
+ if (match = string.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+
+ if (!inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ switch (c) {
+ case '{': if (! inParam) { level ++; chunk.push(c); break }
+ case '}': if (! inParam) { level --; chunk.push(c); chunks[++j] = chunk = []; break }
+ case '(': if (! inParam) { inParam = true; chunk.push(c); break }
+ case ')': if ( inParam) { inParam = false; chunk.push(c); break }
+ default: chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ error = new(LessError)({
+ index: i,
+ type: 'Parse',
+ message: "missing closing `}`",
+ filename: env.filename
+ }, env);
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ if (error) {
+ return callback(error);
+ }
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ try {
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+ } catch (e) {
+ return callback(new(LessError)(e, env));
+ }
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [], importError;
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ throw new(LessError)(e, env);
+ }
+
+ if ((importError = parser.imports.error)) { // Check if there was an error during importing
+ if (importError instanceof LessError) throw importError;
+ else throw new(LessError)(importError, env);
+ }
+
+ if (options.yuicompress && less.mode === 'node') {
+ return require('./cssmin').compressor.cssmin(css);
+ } else if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ type: "Parse",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+
+ if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+ if (tree.colors.hasOwnProperty(k)) {
+ // detect named color
+ return new(tree.Color)(tree.colors[k].slice(1));
+ } else {
+ return new(tree.Keyword)(k);
+ }
+ }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args, index = i;
+
+ if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args, index, env.filename) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.entities.assignment) || $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ // Assignments are argument entities for calls.
+ // They are present in ie filter properties as shown below.
+ //
+ // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+ //
+
+ assignment: function () {
+ var key, value;
+ if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+ return new(tree.Assignment)(key, value);
+ }
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+
+ expect(')');
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index, env.filename);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i), important = false;
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e, i));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if ($(this.important)) {
+ important = true;
+ }
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args || [], index, env.filename, important);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value, cond, variadic = false;
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ save();
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ do {
+ if (input.charAt(i) === '.' && $(/^\.{3}/)) {
+ variadic = true;
+ break;
+ } else if (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ value = expect(this.expression, 'expected expression');
+ params.push({ name: param.name, value: value });
+ } else if ($(/^\.{3}/)) {
+ params.push({ name: param.name, variadic: true });
+ variadic = true;
+ break;
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ } else {
+ break;
+ }
+ } while ($(','))
+
+ expect(')');
+
+ if ($(/^when/)) { // Guard
+ cond = expect(this.conditions, 'expected condition');
+ }
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
+ } else {
+ restore();
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^\(opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ expect(')');
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c, v;
+
+ c = $(this.combinator);
+ e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+ $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+ if (! e) {
+ $('(') && (v = $(this.entities.variable)) && $(')') && (e = new(tree.Paren)(v));
+ }
+
+ if (e) { return new(tree.Element)(c, e, i) }
+
+ if (c.value && c.value.charAt(0) === '&') {
+ return new(tree.Element)(c, null, i);
+ }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === '&') {
+ match = '&';
+ i++;
+ if(input.charAt(i) === ' ') {
+ match = '& ';
+ }
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(match);
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ if ($('(')) {
+ sel = $(this.entity);
+ expect(')');
+ return new(tree.Selector)([new(tree.Element)('', sel, i)]);
+ }
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules, env.strictImports);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path, features, index = i;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url))) {
+ features = $(this.mediaFeatures);
+ if ($(';')) {
+ return new(tree.Import)(path, imports, features, index);
+ }
+ }
+ },
+
+ mediaFeature: function () {
+ var e, p, nodes = [];
+
+ do {
+ if (e = $(this.entities.keyword)) {
+ nodes.push(e);
+ } else if ($('(')) {
+ p = $(this.property);
+ e = $(this.entity);
+ if ($(')')) {
+ if (p && e) {
+ nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+ } else if (e) {
+ nodes.push(new(tree.Paren)(e));
+ } else {
+ return null;
+ }
+ } else { return null }
+ }
+ } while (e);
+
+ if (nodes.length > 0) {
+ return new(tree.Expression)(nodes);
+ }
+ },
+
+ mediaFeatures: function () {
+ var e, features = [];
+
+ do {
+ if (e = $(this.mediaFeature)) {
+ features.push(e);
+ if (! $(',')) { break }
+ } else if (e = $(this.entities.variable)) {
+ features.push(e);
+ if (! $(',')) { break }
+ }
+ } while (e);
+
+ return features.length > 0 ? features : null;
+ },
+
+ media: function () {
+ var features, rules;
+
+ if ($(/^@media/)) {
+ features = $(this.mediaFeatures);
+
+ if (rules = $(this.block)) {
+ return new(tree.Media)(rules, features);
+ }
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types, e, nodes;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import']) || $(this.media)) {
+ return value;
+ } else if (name = $(/^@page|@keyframes/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ conditions: function () {
+ var a, b, index = i, condition;
+
+ if (a = $(this.condition)) {
+ while ($(',') && (b = $(this.condition))) {
+ condition = new(tree.Condition)('or', condition || a, b, index);
+ }
+ return condition || a;
+ }
+ },
+ condition: function () {
+ var a, b, c, op, index = i, negate = false;
+
+ if ($(/^not/)) { negate = true }
+ expect('(');
+ if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+ if (op = $(/^(?:>=|=<|[<=>])/)) {
+ if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+ c = new(tree.Condition)(op, a, b, index, negate);
+ } else {
+ error('expected expression');
+ }
+ } else {
+ c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+ }
+ expect(')');
+ return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (!/^([a-z]+:)?\//.test(path) && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, function (e) {
+ if (e && typeof(env.errback) === "function") {
+ env.errback.call(null, path, paths, callback, env);
+ } else {
+ callback.apply(null, arguments);
+ }
+ }, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fade: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a = amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ return this._math('round', n);
+ },
+ ceil: function (n) {
+ return this._math('ceil', n);
+ },
+ floor: function (n) {
+ return this._math('floor', n);
+ },
+ _math: function (fn, n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math[fn](n);
+ } else {
+ throw { type: "Argument", message: "argument must be a number" };
+ }
+ },
+ argb: function (color) {
+ return new(tree.Anonymous)(color.toARGB());
+
+ },
+ percentage: function (n) {
+ return new(tree.Dimension)(n.value * 100, '%');
+ },
+ color: function (n) {
+ if (n instanceof tree.Quoted) {
+ return new(tree.Color)(n.value.slice(1));
+ } else {
+ throw { type: "Argument", message: "argument must be a string" };
+ }
+ },
+ iscolor: function (n) {
+ return this._isa(n, tree.Color);
+ },
+ isnumber: function (n) {
+ return this._isa(n, tree.Dimension);
+ },
+ isstring: function (n) {
+ return this._isa(n, tree.Quoted);
+ },
+ iskeyword: function (n) {
+ return this._isa(n, tree.Keyword);
+ },
+ isurl: function (n) {
+ return this._isa(n, tree.URL);
+ },
+ ispixel: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+ },
+ ispercentage: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+ },
+ isem: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+ },
+ _isa: function (n, Type) {
+ return (n instanceof Type) ? tree.True : tree.False;
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+ tree.colors = {
+ 'aliceblue':'#f0f8ff',
+ 'antiquewhite':'#faebd7',
+ 'aqua':'#00ffff',
+ 'aquamarine':'#7fffd4',
+ 'azure':'#f0ffff',
+ 'beige':'#f5f5dc',
+ 'bisque':'#ffe4c4',
+ 'black':'#000000',
+ 'blanchedalmond':'#ffebcd',
+ 'blue':'#0000ff',
+ 'blueviolet':'#8a2be2',
+ 'brown':'#a52a2a',
+ 'burlywood':'#deb887',
+ 'cadetblue':'#5f9ea0',
+ 'chartreuse':'#7fff00',
+ 'chocolate':'#d2691e',
+ 'coral':'#ff7f50',
+ 'cornflowerblue':'#6495ed',
+ 'cornsilk':'#fff8dc',
+ 'crimson':'#dc143c',
+ 'cyan':'#00ffff',
+ 'darkblue':'#00008b',
+ 'darkcyan':'#008b8b',
+ 'darkgoldenrod':'#b8860b',
+ 'darkgray':'#a9a9a9',
+ 'darkgrey':'#a9a9a9',
+ 'darkgreen':'#006400',
+ 'darkkhaki':'#bdb76b',
+ 'darkmagenta':'#8b008b',
+ 'darkolivegreen':'#556b2f',
+ 'darkorange':'#ff8c00',
+ 'darkorchid':'#9932cc',
+ 'darkred':'#8b0000',
+ 'darksalmon':'#e9967a',
+ 'darkseagreen':'#8fbc8f',
+ 'darkslateblue':'#483d8b',
+ 'darkslategray':'#2f4f4f',
+ 'darkslategrey':'#2f4f4f',
+ 'darkturquoise':'#00ced1',
+ 'darkviolet':'#9400d3',
+ 'deeppink':'#ff1493',
+ 'deepskyblue':'#00bfff',
+ 'dimgray':'#696969',
+ 'dimgrey':'#696969',
+ 'dodgerblue':'#1e90ff',
+ 'firebrick':'#b22222',
+ 'floralwhite':'#fffaf0',
+ 'forestgreen':'#228b22',
+ 'fuchsia':'#ff00ff',
+ 'gainsboro':'#dcdcdc',
+ 'ghostwhite':'#f8f8ff',
+ 'gold':'#ffd700',
+ 'goldenrod':'#daa520',
+ 'gray':'#808080',
+ 'grey':'#808080',
+ 'green':'#008000',
+ 'greenyellow':'#adff2f',
+ 'honeydew':'#f0fff0',
+ 'hotpink':'#ff69b4',
+ 'indianred':'#cd5c5c',
+ 'indigo':'#4b0082',
+ 'ivory':'#fffff0',
+ 'khaki':'#f0e68c',
+ 'lavender':'#e6e6fa',
+ 'lavenderblush':'#fff0f5',
+ 'lawngreen':'#7cfc00',
+ 'lemonchiffon':'#fffacd',
+ 'lightblue':'#add8e6',
+ 'lightcoral':'#f08080',
+ 'lightcyan':'#e0ffff',
+ 'lightgoldenrodyellow':'#fafad2',
+ 'lightgray':'#d3d3d3',
+ 'lightgrey':'#d3d3d3',
+ 'lightgreen':'#90ee90',
+ 'lightpink':'#ffb6c1',
+ 'lightsalmon':'#ffa07a',
+ 'lightseagreen':'#20b2aa',
+ 'lightskyblue':'#87cefa',
+ 'lightslategray':'#778899',
+ 'lightslategrey':'#778899',
+ 'lightsteelblue':'#b0c4de',
+ 'lightyellow':'#ffffe0',
+ 'lime':'#00ff00',
+ 'limegreen':'#32cd32',
+ 'linen':'#faf0e6',
+ 'magenta':'#ff00ff',
+ 'maroon':'#800000',
+ 'mediumaquamarine':'#66cdaa',
+ 'mediumblue':'#0000cd',
+ 'mediumorchid':'#ba55d3',
+ 'mediumpurple':'#9370d8',
+ 'mediumseagreen':'#3cb371',
+ 'mediumslateblue':'#7b68ee',
+ 'mediumspringgreen':'#00fa9a',
+ 'mediumturquoise':'#48d1cc',
+ 'mediumvioletred':'#c71585',
+ 'midnightblue':'#191970',
+ 'mintcream':'#f5fffa',
+ 'mistyrose':'#ffe4e1',
+ 'moccasin':'#ffe4b5',
+ 'navajowhite':'#ffdead',
+ 'navy':'#000080',
+ 'oldlace':'#fdf5e6',
+ 'olive':'#808000',
+ 'olivedrab':'#6b8e23',
+ 'orange':'#ffa500',
+ 'orangered':'#ff4500',
+ 'orchid':'#da70d6',
+ 'palegoldenrod':'#eee8aa',
+ 'palegreen':'#98fb98',
+ 'paleturquoise':'#afeeee',
+ 'palevioletred':'#d87093',
+ 'papayawhip':'#ffefd5',
+ 'peachpuff':'#ffdab9',
+ 'peru':'#cd853f',
+ 'pink':'#ffc0cb',
+ 'plum':'#dda0dd',
+ 'powderblue':'#b0e0e6',
+ 'purple':'#800080',
+ 'red':'#ff0000',
+ 'rosybrown':'#bc8f8f',
+ 'royalblue':'#4169e1',
+ 'saddlebrown':'#8b4513',
+ 'salmon':'#fa8072',
+ 'sandybrown':'#f4a460',
+ 'seagreen':'#2e8b57',
+ 'seashell':'#fff5ee',
+ 'sienna':'#a0522d',
+ 'silver':'#c0c0c0',
+ 'skyblue':'#87ceeb',
+ 'slateblue':'#6a5acd',
+ 'slategray':'#708090',
+ 'slategrey':'#708090',
+ 'snow':'#fffafa',
+ 'springgreen':'#00ff7f',
+ 'steelblue':'#4682b4',
+ 'tan':'#d2b48c',
+ 'teal':'#008080',
+ 'thistle':'#d8bfd8',
+ 'tomato':'#ff6347',
+ 'turquoise':'#40e0d0',
+ 'violet':'#ee82ee',
+ 'wheat':'#f5deb3',
+ 'white':'#ffffff',
+ 'whitesmoke':'#f5f5f5',
+ 'yellow':'#ffff00',
+ 'yellowgreen':'#9acd32'
+ };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+ this.key = key;
+ this.value = val;
+};
+tree.Assignment.prototype = {
+ toCSS: function () {
+ return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+ this.name = name;
+ this.args = args;
+ this.index = index;
+ this.filename = filename;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ try {
+ return tree.functions[this.name].apply(tree.functions, args);
+ } catch (e) {
+ throw { type: e.type || "Runtime",
+ message: "error evaluating function `" + this.name + "`" +
+ (e.message ? ': ' + e.message : ''),
+ index: this.index, filename: this.filename };
+ }
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ },
+ toARGB: function () {
+ var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+ return '#' + argb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+ this.op = op.trim();
+ this.lvalue = l;
+ this.rvalue = r;
+ this.index = i;
+ this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+ var a = this.lvalue.eval(env),
+ b = this.rvalue.eval(env);
+
+ var i = this.index, result;
+
+ var result = (function (op) {
+ switch (op) {
+ case 'and':
+ return a && b;
+ case 'or':
+ return a || b;
+ default:
+ if (a.compare) {
+ result = a.compare(b);
+ } else if (b.compare) {
+ result = b.compare(a);
+ } else {
+ throw { type: "Type",
+ message: "Unable to perform comparison",
+ index: i };
+ }
+ switch (result) {
+ case -1: return op === '<' || op === '=<';
+ case 0: return op === '=' || op === '>=' || op === '=<';
+ case 1: return op === '>' || op === '>=';
+ }
+ }
+ })(this.op);
+ return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ },
+
+ // TODO: Perform unit conversion before comparing
+ compare: function (other) {
+ if (other instanceof tree.Dimension) {
+ if (other.value > this.value) {
+ return -1;
+ } else if (other.value < this.value) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ return -1;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value, features) {
+ this.name = name;
+
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ this.ruleset.allowImports = true;
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+
+ if (typeof(value) === 'string') {
+ this.value = value.trim();
+ } else if (value) {
+ this.value = value;
+ } else {
+ this.value = "";
+ }
+ this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+ return new(tree.Element)(this.combinator,
+ this.value.eval ? this.value.eval(env) : this.value,
+ this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + (this.value.toCSS ? this.value.toCSS(env) : this.value);
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else if (value === '& ') {
+ this.value = '& ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ '& ' : ' ',
+ ':' : ' :',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS ? e.toCSS(env) : '';
+ }).join(' ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, index) {
+ var that = this;
+
+ this.index = index;
+ this._path = path;
+ this.features = features && new(tree.Value)(features);
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css(\?.*)?$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (e, root) {
+ if (e) { e.index = index }
+ that.root = root || new(tree.Ruleset)([], []);
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function (env) {
+ var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+ if (this.css) {
+ return "@import " + this._path.toCSS() + features + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset, features = this.features && this.features.eval(env);
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value },
+ compare: function (other) {
+ if (other instanceof tree.Keyword) {
+ return other.value === this.value ? 0 : 1;
+ } else {
+ return -1;
+ }
+ }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Media = function (value, features) {
+ var el = new(tree.Element)('&', null, 0),
+ selectors = [new(tree.Selector)([el])];
+
+ this.features = new(tree.Value)(features);
+ this.ruleset = new(tree.Ruleset)(selectors, value);
+ this.ruleset.allowImports = true;
+};
+tree.Media.prototype = {
+ toCSS: function (ctx, env) {
+ var features = this.features.toCSS(env);
+
+ this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
+ return '@media ' + features + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ },
+ eval: function (env) {
+ if (!env.mediaBlocks) {
+ env.mediaBlocks = [];
+ env.mediaPath = [];
+ }
+
+ var blockIndex = env.mediaBlocks.length;
+ env.mediaPath.push(this);
+ env.mediaBlocks.push(this);
+
+ var media = new(tree.Media)([], []);
+ media.features = this.features.eval(env);
+
+ env.frames.unshift(this.ruleset);
+ media.ruleset = this.ruleset.eval(env);
+ env.frames.shift();
+
+ env.mediaBlocks[blockIndex] = media;
+ env.mediaPath.pop();
+
+ return env.mediaPath.length === 0 ? media.evalTop(env) :
+ media.evalNested(env)
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) },
+
+ evalTop: function (env) {
+ var result = this;
+
+ // Render all dependent Media blocks.
+ if (env.mediaBlocks.length > 1) {
+ var el = new(tree.Element)('&', null, 0);
+ var selectors = [new(tree.Selector)([el])];
+ result = new(tree.Ruleset)(selectors, env.mediaBlocks);
+ result.multiMedia = true;
+ }
+
+ delete env.mediaBlocks;
+ delete env.mediaPath;
+
+ return result;
+ },
+ evalNested: function (env) {
+ var i, value,
+ path = env.mediaPath.concat([this]);
+
+ // Extract the media-query conditions separated with `,` (OR).
+ for (i = 0; i < path.length; i++) {
+ value = path[i].features instanceof tree.Value ?
+ path[i].features.value : path[i].features;
+ path[i] = Array.isArray(value) ? value : [value];
+ }
+
+ // Trace all permutations to generate the resulting media-query.
+ //
+ // (a, b and c) with nested (d, e) ->
+ // a and d
+ // a and e
+ // b and c and d
+ // b and c and e
+ this.features = new(tree.Value)(this.permute(path).map(function (path) {
+ path = path.map(function (fragment) {
+ return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment);
+ });
+
+ for(i = path.length - 1; i > 0; i--) {
+ path.splice(i, 0, new(tree.Anonymous)("and"));
+ }
+
+ return new(tree.Expression)(path);
+ }));
+
+ // Fake a tree-node that doesn't output anything.
+ return new(tree.Ruleset)([], []);
+ },
+ permute: function (arr) {
+ if (arr.length === 0) {
+ return [];
+ } else if (arr.length === 1) {
+ return arr[0];
+ } else {
+ var result = [];
+ var rest = this.permute(arr.slice(1));
+ for (var i = 0; i < rest.length; i++) {
+ for (var j = 0; j < arr[0].length; j++) {
+ result.push([arr[0][j]].concat(rest[i]));
+ }
+ }
+ return result;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+ this.filename = filename;
+ this.important = important;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments, this.important).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { type: 'Runtime',
+ message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index, filename: this.filename };
+ }
+ }
+ }
+ throw { type: 'Name',
+ message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index, filename: this.filename };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition, variadic) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.condition = condition;
+ this.variadic = variadic;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ evalParams: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []), varargs;
+
+ for (var i = 0, val, name; i < this.params.length; i++) {
+ if (name = this.params[i].name) {
+ if (this.params[i].variadic && args) {
+ varargs = [];
+ for (var j = i; j < args.length; j++) {
+ varargs.push(args[j].eval(env));
+ }
+ frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
+ } else if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(name, val.eval(env)));
+ } else {
+ throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ return frame;
+ },
+ eval: function (env, args, important) {
+ var frame = this.evalParams(env, args), context, _arguments = [], rules, start;
+
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ rules = important ?
+ this.rules.map(function (r) {
+ return new(tree.Rule)(r.name, r.value, '!important', r.index);
+ }) : this.rules.slice(0);
+
+ return new(tree.Ruleset)(null, rules).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len, frame;
+
+ if (! this.variadic) {
+ if (argsLength < this.required) { return false }
+ if (argsLength > this.params.length) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+ }
+
+ if (this.condition && !this.condition.eval({
+ frames: [this.evalParams(env, args)].concat(env.frames)
+ })) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+ this.value = node;
+};
+tree.Paren.prototype = {
+ toCSS: function (env) {
+ return '(' + this.value.toCSS(env) + ')';
+ },
+ eval: function (env) {
+ return new(tree.Paren)(this.value.eval(env));
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return ('value' in v) ? v.value : v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+ this.inline = inline || false;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + (this.inline ? "" : ";");
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name,
+ this.value.eval(context),
+ this.important,
+ this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules, strictImports) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+ this.strictImports = strictImports;
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+ var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports);
+
+ ruleset.root = this.root;
+ ruleset.allowImports = this.allowImports;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > rule.selectors[j].elements.length) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ this.joinSelectors(paths, context, this.selectors);
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive) || (rule instanceof tree.Media)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join( env.compress ? ',' : ',\n');
+
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ },
+
+ joinSelectors: function (paths, context, selectors) {
+ for (var s = 0; s < selectors.length; s++) {
+ this.joinSelector(paths, context, selectors[s]);
+ }
+ },
+
+ joinSelector: function (paths, context, selector) {
+ var before = [], after = [], beforeElements = [],
+ afterElements = [], hasParentSelector = false, el;
+
+ for (var i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ if (el.combinator.value.charAt(0) === '&') {
+ hasParentSelector = true;
+ }
+ if (hasParentSelector) afterElements.push(el);
+ else beforeElements.push(el);
+ }
+
+ if (! hasParentSelector) {
+ afterElements = beforeElements;
+ beforeElements = [];
+ }
+
+ if (beforeElements.length > 0) {
+ before.push(new(tree.Selector)(beforeElements));
+ }
+
+ if (afterElements.length > 0) {
+ after.push(new(tree.Selector)(afterElements));
+ }
+
+ for (var c = 0; c < context.length; c++) {
+ paths.push(before.concat(context[c]).concat(after));
+ }
+ }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ var len = this.elements.length,
+ olen = other.elements.length,
+ max = Math.min(len, olen);
+
+ if (len < olen) {
+ return false;
+ } else {
+ for (var i = 0; i < max; i++) {
+ if (this.elements[i].value !== other.elements[i].value) {
+ return false;
+ }
+ }
+ }
+ return true;
+};
+tree.Selector.prototype.eval = function (env) {
+ return new(tree.Selector)(this.elements.map(function (e) {
+ return e.eval(env);
+ }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (typeof(window) !== 'undefined' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { type: 'Name',
+ message: "variable " + name + " is undefined",
+ filename: this.file,
+ index: this.index };
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+tree.jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+
+})(require('./tree'));
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:' ||
+ location.protocol === 'chrome:' ||
+ location.protocol === 'chrome-extension:' ||
+ location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (e, root, _, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (e, root, _, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+ var css = tree.toCSS();
+ var style = styles[i];
+ style.type = 'text/css';
+ if (style.styleSheet) {
+ style.styleSheet.cssText = css;
+ } else {
+ style.innerHTML = css;
+ }
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^(https?|file):/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+ var filename = href.match(/([^\/]+)$/)[1];
+
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, null, data, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type,
+ filename: filename
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ css.media = sheet.media || 'screen';
+ css.id = id;
+ document.getElementsByTagName('head')[0].appendChild(css);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? false : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol) {
+ if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+ var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+ var elem = document.createElement('div'), timer, content, error = [];
+ var filename = e.filename || href;
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p>in <a href="' + filename + '">' + filename + "</a> ";
+
+ var errorline = function (e, i, classname) {
+ if (e.extract[i]) {
+ error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
+ .replace(/\{class\}/, classname)
+ .replace(/\{content\}/, e.extract[i]));
+ }
+ };
+
+ if (e.stack) {
+ content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+ } else if (e.extract) {
+ errorline(e, 0, '');
+ errorline(e, 1, 'line');
+ errorline(e, 2, '');
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ '<ul>' + error.join('') + '</ul>';
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #dd6666;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.line {',
+ 'color: #ff0000;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless130minjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0.min.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0.min.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0.min.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+//
+// LESS - Leaner CSS v1.3.0
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function c(b){return a.less[b.split("/")[1]]}function l(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(j)&&(new d.Parser).parse(a[b].innerHTML||"",function(c,d){var e=d.toCSS(),f=a[b];f.type="text/css",f.styleSheet?f.styleSheet.cssText=e:f.innerHTML=e})}function m(a,b){for(var c=0;c<d.sheets.length;c++)n(d.sheets[c],a,b,d.sheets.length-(c+1))}function n(b,c,e,f){var h=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/,""),j=g&&g.getItem(i),k=g&&g.getItem(i+":timestamp"),l={css:j,timestamp:k};/^(https?|file):/.test(i)||(i.charAt(0)=="/"?i=a.location.protocol+"//"+a.location.host+i:i=h.slice(0,h.lastIndexOf("/")+1)+i);var m=i.match(/([^\/]+)$/)[1];q(b.href,b.type,function(a,g){if(!e&&l&&g&&(new Date(g)).valueOf()===(new Date(l.timestamp)).valueOf())p(l.css,b),c(nul
l,null,a,b,{local:!0,remaining:f});else try{(new d.Parser({optimization:d.optimization,paths:[i.replace(/[\w\.-]+$/,"")],mime:b.type,filename:m})).parse(a,function(d,e){if(d)return u(d,i);try{c(d,e,a,b,{local:!1,lastModified:g,remaining:f}),s(document.getElementById("less-error-message:"+o(i)))}catch(d){u(d,i)}})}catch(h){u(h,i)}},function(a,b){throw new Error("Couldn't load "+b+" ("+a+")")})}function o(a){return a.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\?.*$/,"").replace(/\.[^\.\/]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function p(a,b,c){var d,e=b.href?b.href.replace(/\?.*$/,""):"",f="less:"+(b.title||o(e));(d=document.getElementById(f))===null&&(d=document.createElement("style"),d.type="text/css",d.media=b.media||"screen",d.id=f,document.getElementsByTagName("head&qu
ot;)[0].appendChild(d));if(d.styleSheet)try{d.styleSheet.cssText=a}catch(h){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(a){d.childNodes.length>0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&g&&(t("saving "+e+" to cache."),g.setItem(e,a),g.setItem(e+":timestamp",c))}function q(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var g=r(),h=f?!1:d.async;typeof g.overrideMimeType=="function"&&g.overrideMimeType("text/css"),g.open("GET",a,h),g.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),g.send(null),f?g.status===0||g.status>=200&&g.status<300?c(g.responseText):e(g.status,a):h?g.onreadystat
echange=function(){g.readyState==4&&i(g,c,e)}:i(g,c,e)}function r(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){return t("browser doesn't support AJAX."),null}}function s(a){return a&&a.parentNode.removeChild(a)}function t(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: "+a)}function u(a,b){var c="less-error-message:"+o(b),e='<li><label>{line}</label><pre class="{class}">{content}</pre></li>',f=document.createElement("div"),g,h,i=[],j=a.filename||b;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p>in <a href="'+j+'">'+j+"</a> ";var k=function(a,b,c){a.extract[b]&&i.push(e.replace(/\{line\}/,par
seInt(a.line)+(b-1)).replace(/\{class\}/,c).replace(/\{content\}/,a.extract[b]))};a.stack?h+="<br/>"+a.stack.split("\n").slice(1).join("<br/>"):a.extract&&(k(a,0,""),k(a,1,"line"),k(a,2,""),h+="on line "+a.line+", column "+(a.column+1)+":</p>"+"<ul>"+i.join("")+"</ul>"),f.innerHTML=h,p([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-mes
sage pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=setInterval(function(){document.body&&(document.getElemen
tById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}typeof define=="function"&&define.amd&&define("less",[],function(){return d}),Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d<c;d++)d in this&&a.call(b,this[d],d,this)}),Array.prototype.map||(Array.prototype.map=function(a){var b=this.length>>>0,c=new Array(b),d=arguments[1];for(var e=0;e<b;e++)e in this&&(c[e]=a.call(d,this[e],e,this));return c}),Array.prototype.filter||(Array.prototype.filter=function(a){var b=[],c=arguments[1];for(var d=0;d<this.length;d++)a.call(c,this[d])&&b.push(this[d]);return b}),Array.prototype.reduce||(Array.prototype.reduce=function(a){var b=thi
s.length>>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.length>=2)var d=arguments[1];else do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0);for(;c<b;c++)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){var b=this.length,c=arguments[1]||0;if(!b)return-1;if(c>=b)return-1;c<0&&(c+=b);for(;c<b;c++){if(!Object.prototype.hasOwnProperty.call(this,c))continue;if(a===this[c])return c}return-1}),Object.keys||(Object.keys=function(a){var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}),String.prototype.trim||(String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")});var d,e;typeof environment=="object"&&{}.toString.call(environment)==="[object Environment]"?(typeof a=="undefined"?d={}:d=a.
less={},e=d.tree={},d.mode="rhino"):typeof a=="undefined"?(d=exports,e=c("./tree"),d.mode="node"):(typeof a.less=="undefined"&&(a.less={}),d=a.less,e=a.less.tree={},d.mode="browser"),d.Parser=function v(a){function q(){h=k[g],i=f,l=f}function r(){k[g]=h,f=i,l=f}function s(){f>l&&(k[g]=k[g].slice(f-l),l=f)}function t(a){var c,d,e,h,i,j,n,o;if(a instanceof Function)return a.call(m.parsers);if(typeof a=="string")c=b.charAt(f)===a?a:null,e=1,s();else{s();if(c=a.exec(k[g]))e=c[0].length;else return null}if(c){o=f+=e,j=f+k[g].length-e;while(f<j){h=b.charCodeAt(f);if(h!==32&&h!==10&&h!==9)break;f++}return k[g]=k[g].slice(e+(f-o)),l=f,k[g].length===0&&g<k.length-1&&g++,typeof c=="string"?c:c.length===1?c[0]:c}}function u(a,c){var d=t(a);if(!d)v(c||(typeof a=="string"?"expected '"+a+"' got '"+b.charAt(f)+"'":"une
xpected token"));else return d}function v(a,b){throw{index:f,type:b||"Syntax",message:a}}function w(a){return typeof a=="string"?b.charAt(f)===a:a.test(k[g])?!0:!1}function x(a){return d.mode==="node"?c("path").basename(a):a.match(/[^\/]+$/)[0]}function y(a,c){return a.filename&&c.filename&&a.filename!==c.filename?m.imports.contents[x(a.filename)]:b}function z(a,b){for(var c=a,d=-1;c>=0&&b.charAt(c)!=="\n";c--)d++;return{line:typeof a=="number"?(b.slice(0,a).match(/\n/g)||"").length:null,column:d}}function A(a,b){var c=y(a,b),d=z(a.index,c),e=d.line,f=d.column,g=c.split("\n");this.type=a.type||"Syntax",this.message=a.message,this.filename=a.filename||b.filename,this.index=a.index,this.line=typeof e=="number"?e+1:null,this.callLine=a.call&&z(a.call,c).line+1,this.callExtract=g[z(a.call,c).line],this.stack=a.stack,this.column=f,this.extract=[g[e-1
],g[e],g[e+1]]}var b,f,g,h,i,j,k,l,m,n=this,o=function(){},p=this.imports={paths:a&&a.paths||[],queue:[],files:{},contents:{},mime:a&&a.mime,error:null,push:function(b,c){var e=this;this.queue.push(b),d.Parser.importer(b,this.paths,function(a,d,f){e.queue.splice(e.queue.indexOf(b),1),e.files[b]=d,e.contents[b]=f,a&&!e.error&&(e.error=a),c(a,d),e.queue.length===0&&o()},a)}};return this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.filename=this.env.filename||null,m={imports:p,parse:function(h,i){var n,p,q,r,s,u,v=[],w,x=null;f=g=l=j=0,b=h.replace(/\r\n/g,"\n"),k=function(c){var d=0,e=/[^"'`\{\}\/\(\)\\]+/g,f=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,g=/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`\\\r\n]|\\.)*)`/g,h=0,i,j=c[0],k;for(var l=0,m,n;l<b.length;l++){e.lastIndex=l,(i=e.exec(b))&&i.index===l&&(l+=i[0].length,j.push(i[0])),m=b.c
harAt(l),f.lastIndex=g.lastIndex=l,(i=g.exec(b))&&i.index===l&&(l+=i[0].length,j.push(i[0]),m=b.charAt(l)),!k&&m==="/"&&(n=b.charAt(l+1),(n==="/"||n==="*")&&(i=f.exec(b))&&i.index===l&&(l+=i[0].length,j.push(i[0]),m=b.charAt(l)));switch(m){case"{":if(!k){h++,j.push(m);break};case"}":if(!k){h--,j.push(m),c[++d]=j=[];break};case"(":if(!k){k=!0,j.push(m);break};case")":if(k){k=!1,j.push(m);break};default:j.push(m)}}return h>0&&(x=new A({index:l,type:"Parse",message:"missing closing `}`",filename:a.filename},a)),c.map(function(a){return a.join("")})}([[]]);if(x)return i(x);try{n=new e.Ruleset([],t(this.parsers.primary)),n.root=!0}catch(y){return i(new A(y,a))}n.toCSS=function(b){var f,g,h;return function(f,g){var h=[],i;f=f||{},typeof g=="object"&&!Array.isArray(g)&&(g=Object.keys(g).map(function(
a){var b=g[a];return b instanceof e.Value||(b instanceof e.Expression||(b=new e.Expression([b])),b=new e.Value([b])),new e.Rule("@"+a,b,!1,0)}),h=[new e.Ruleset(null,g)]);try{var j=b.call(this,{frames:h}).toCSS([],{compress:f.compress||!1})}catch(k){throw new A(k,a)}if(i=m.imports.error)throw i instanceof A?i:new A(i,a);return f.yuicompress&&d.mode==="node"?c("./cssmin").compressor.cssmin(j):f.compress?j.replace(/(\s)+/g,"$1"):j}}(n.eval);if(f<b.length-1){f=j,u=b.split("\n"),s=(b.slice(0,f).match(/\n/g)||"").length+1;for(var z=f,B=-1;z>=0&&b.charAt(z)!=="\n";z--)B++;x={type:"Parse",message:"Syntax Error on line "+s,index:f,filename:a.filename,line:s,column:B,extract:[u[s-2],u[s-1],u[s]]}}this.imports.queue.length>0?o=function(){i(x,n)}:i(x,n)},parsers:{primary:function(){var a,b=[];while((a=t(this.mixin.definition)||t(this.rule)||t(this.ruleset)||t(this.mixin.call)||t(t
his.comment)||t(this.directive))||t(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(b.charAt(f)!=="/")return;if(b.charAt(f+1)==="/")return new e.Comment(t(/^\/\/.*/),!0);if(a=t(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new e.Comment(a)},entities:{quoted:function(){var a,c=f,d;b.charAt(c)==="~"&&(c++,d=!0);if(b.charAt(c)!=='"'&&b.charAt(c)!=="'")return;d&&t("~");if(a=t(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new e.Quoted(a[0],a[1]||a[2],d)},keyword:function(){var a;if(a=t(/^[_A-Za-z-][_A-Za-z0-9-]*/))return e.colors.hasOwnProperty(a)?new e.Color(e.colors[a].slice(1)):new e.Keyword(a)},call:function(){var b,c,d=f;if(!(b=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(k[g])))return;b=b[1].toLowerCase();if(b==="url")return null;f+=b.length;if(b==="alpha")return t(this.alpha);t("("),c=t(this.entities.arguments);if(!t(")"))ret
urn;if(b)return new e.Call(b,c,d,a.filename)},arguments:function(){var a=[],b;while(b=t(this.entities.assignment)||t(this.expression)){a.push(b);if(!t(","))break}return a},literal:function(){return t(this.entities.dimension)||t(this.entities.color)||t(this.entities.quoted)},assignment:function(){var a,b;if((a=t(/^\w+(?=\s?=)/i))&&t("=")&&(b=t(this.entity)))return new e.Assignment(a,b)},url:function(){var a;if(b.charAt(f)!=="u"||!t(/^url\(/))return;return a=t(this.entities.quoted)||t(this.entities.variable)||t(this.entities.dataURI)||t(/^[-\w%@$\/.&=:;#+?~]+/)||"",u(")"),new e.URL(a.value||a.data||a instanceof e.Variable?a:new e.Anonymous(a),p.paths)},dataURI:function(){var a;if(t(/^data:/)){a={},a.mime=t(/^[^\/]+\/[^,;)]+/)||"",a.charset=t(/^;\s*charset=[^,;)]+/)||"",a.base64=t(/^;\s*base64/)||"",a.data=t(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var c,d=f;if(b.charAt(f)=
=="@"&&(c=t(/^@@?[\w-]+/)))return new e.Variable(c,d,a.filename)},color:function(){var a;if(b.charAt(f)==="#"&&(a=t(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new e.Color(a[1])},dimension:function(){var a,c=b.charCodeAt(f);if(c>57||c<45||c===47)return;if(a=t(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new e.Dimension(a[1],a[2])},javascript:function(){var a,c=f,d;b.charAt(c)==="~"&&(c++,d=!0);if(b.charAt(c)!=="`")return;d&&t("~");if(a=t(/^`([^`]*)`/))return new e.JavaScript(a[1],f,d)}},variable:function(){var a;if(b.charAt(f)==="@"&&(a=t(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!w(/^[@\w.%-]+\/[@\w.-]+/))return;if((a=t(this.entity))&&t("/")&&(b=t(this.entity)))return new e.Shorthand(a,b)},mixin:{call:function(){var c=[],d,g,h,i=f,j=b.charAt(f),k=!1;if(j!=="."&&j!=="#"
;)return;while(d=t(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))c.push(new e.Element(g,d,f)),g=t(">");t("(")&&(h=t(this.entities.arguments))&&t(")"),t(this.important)&&(k=!0);if(c.length>0&&(t(";")||w("}")))return new e.mixin.Call(c,h||[],i,a.filename,k)},definition:function(){var a,c=[],d,g,h,i,j,k=!1;if(b.charAt(f)!=="."&&b.charAt(f)!=="#"||w(/^[^{]*(;|})/))return;q();if(d=t(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=d[1];do{if(b.charAt(f)==="."&&t(/^\.{3}/)){k=!0;break}if(!(h=t(this.entities.variable)||t(this.entities.literal)||t(this.entities.keyword)))break;if(h instanceof e.Variable)if(t(":"))i=u(this.expression,"expected expression"),c.push({name:h.name,value:i});else{if(t(/^\.{3}/)){c.push({name:h.name,variadic:!0}),k=!0;break}c.push({name:h.name})}else c.push({value:h})}while(t(",&q
uot;));u(")"),t(/^when/)&&(j=u(this.conditions,"expected condition")),g=t(this.block);if(g)return new e.mixin.Definition(a,c,g,j,k);r()}}},entity:function(){return t(this.entities.literal)||t(this.entities.variable)||t(this.entities.url)||t(this.entities.call)||t(this.entities.keyword)||t(this.entities.javascript)||t(this.comment)},end:function(){return t(";")||w("}")},alpha:function(){var a;if(!t(/^\(opacity=/i))return;if(a=t(/^\d+/)||t(this.entities.variable))return u(")"),new e.Alpha(a)},element:function(){var a,b,c,d;c=t(this.combinator),a=t(/^(?:\d+\.\d+|\d+)%/)||t(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||t("*")||t(this.attribute)||t(/^\([^)@]+\)/),a||t("(")&&(d=t(this.entities.variable))&&t(")")&&(a=new e.Paren(d));if(a)return new e.Element(c,a,f);if(c.value&&c.value.charAt(0)==="&")return new e.Element(c,null,f)},combin
ator:function(){var a,c=b.charAt(f);if(c===">"||c==="+"||c==="~"){f++;while(b.charAt(f)===" ")f++;return new e.Combinator(c)}if(c==="&"){a="&",f++,b.charAt(f)===" "&&(a="& ");while(b.charAt(f)===" ")f++;return new e.Combinator(a)}return b.charAt(f-1)===" "?new e.Combinator(" "):new e.Combinator(null)},selector:function(){var a,c,d=[],g,h;if(t("("))return a=t(this.entity),u(")"),new e.Selector([new e.Element("",a,f)]);while(c=t(this.element)){g=b.charAt(f),d.push(c);if(g==="{"||g==="}"||g===";"||g===",")break}if(d.length>0)return new e.Selector(d)},tag:function(){return t(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||t("*")},attribute:function(){var a="",b,c,d;if(!t("["))return;if(b=t(/^[a-zA-Z-]+/)||t(this.entities.quoted))(d=t(/^[|~*$^]?=/))&&(c=t(this.entit
ies.quoted)||t(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!t("]"))return;if(a)return"["+a+"]"},block:function(){var a;if(t("{")&&(a=t(this.primary))&&t("}"))return a},ruleset:function(){var b=[],c,d,g;q();while(c=t(this.selector)){b.push(c),t(this.comment);if(!t(","))break;t(this.comment)}if(b.length>0&&(d=t(this.block)))return new e.Ruleset(b,d,a.strictImports);j=f,r()},rule:function(){var a,c,d=b.charAt(f),h,l;q();if(d==="."||d==="#"||d==="&")return;if(a=t(this.variable)||t(this.property)){a.charAt(0)!="@"&&(l=/^([^@+\/'"*`(;{}-]*);/.exec(k[g]))?(f+=l[0].length-1,c=new e.Anonymous(l[1])):a==="font"?c=t(this.font):c=t(this.value),h=t(this.important);if(c&&t(this.end))return new e.Rule(a,c,h,i);j=f,r()}},"import":function(){var a,b,c=f;if(t(/^@import\s+/)&&(a=t(this.entities.quoted)|
|t(this.entities.url))){b=t(this.mediaFeatures);if(t(";"))return new e.Import(a,p,b,c)}},mediaFeature:function(){var a,b,c=[];do if(a=t(this.entities.keyword))c.push(a);else if(t("(")){b=t(this.property),a=t(this.entity);if(!t(")"))return null;if(b&&a)c.push(new e.Paren(new e.Rule(b,a,null,f,!0)));else if(a)c.push(new e.Paren(a));else return null}while(a);if(c.length>0)return new e.Expression(c)},mediaFeatures:function(){var a,b=[];do if(a=t(this.mediaFeature)){b.push(a);if(!t(","))break}else if(a=t(this.entities.variable)){b.push(a);if(!t(","))break}while(a);return b.length>0?b:null},media:function(){var a,b;if(t(/^@media/)){a=t(this.mediaFeatures);if(b=t(this.block))return new e.Media(b,a)}},directive:function(){var a,c,d,g,h,i;if(b.charAt(f)!=="@")return;if(c=t(this["import"])||t(this.media))return c;if(a=t(/^@page|@keyframes/)||t(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)){g=(t(/^[^{]+/)||"&
quot;).trim();if(d=t(this.block))return new e.Directive(a+" "+g,d)}else if(a=t(/^@[-a-z]+/))if(a==="@font-face"){if(d=t(this.block))return new e.Directive(a,d)}else if((c=t(this.entity))&&t(";"))return new e.Directive(a,c)},font:function(){var a=[],b=[],c,d,f,g;while(g=t(this.shorthand)||t(this.entity))b.push(g);a.push(new e.Expression(b));if(t(","))while(g=t(this.expression)){a.push(g);if(!t(","))break}return new e.Value(a)},value:function(){var a,b=[],c;while(a=t(this.expression)){b.push(a);if(!t(","))break}if(b.length>0)return new e.Value(b)},important:function(){if(b.charAt(f)==="!")return t(/^! *important/)},sub:function(){var a;if(t("(")&&(a=t(this.expression))&&t(")"))return a},multiplication:function(){var a,b,c,d;if(a=t(this.operand)){while(!w(/^\/\*/)&&(c=t("/")||t("*"))&&(b=t(this.operand)))d=new e.Operation(c,[d||a,b]);r
eturn d||a}},addition:function(){var a,c,d,g;if(a=t(this.multiplication)){while((d=t(/^[-+]\s+/)||b.charAt(f-1)!=" "&&(t("+")||t("-")))&&(c=t(this.multiplication)))g=new e.Operation(d,[g||a,c]);return g||a}},conditions:function(){var a,b,c=f,d;if(a=t(this.condition)){while(t(",")&&(b=t(this.condition)))d=new e.Condition("or",d||a,b,c);return d||a}},condition:function(){var a,b,c,d,g=f,h=!1;t(/^not/)&&(h=!0),u("(");if(a=t(this.addition)||t(this.entities.keyword)||t(this.entities.quoted))return(d=t(/^(?:>=|=<|[<=>])/))?(b=t(this.addition)||t(this.entities.keyword)||t(this.entities.quoted))?c=new e.Condition(d,a,b,g,h):v("expected expression"):c=new e.Condition("=",a,new e.Keyword("true"),g,h),u(")"),t(/^and/)?new e.Condition("and",c,t(this.condition)):c},operand:function(){var a,c=b.charAt(f+1);b.charAt(f)==="-"&&(c
==="@"||c==="(")&&(a=t("-"));var d=t(this.sub)||t(this.entities.dimension)||t(this.entities.color)||t(this.entities.variable)||t(this.entities.call);return a?new e.Operation("*",[new e.Dimension(-1),d]):d},expression:function(){var a,b,c=[],d;while(a=t(this.addition)||t(this.entity))c.push(a);if(c.length>0)return new e.Expression(c)},property:function(){var a;if(a=t(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}};if(d.mode==="browser"||d.mode==="rhino")d.Parser.importer=function(a,b,c,d){!/^([a-z]+:)?\//.test(a)&&b.length>0&&(a=b[0]+a),n({href:a,title:a,type:d.mime},function(e){e&&typeof d.errback=="function"?d.errback.call(null,a,b,c,d):c.apply(null,arguments)},!0)};(function(a){function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{
error:"RuntimeError",message:"color functions take numbers as parameters"}}function d(a){return Math.min(1,Math.max(0,a))}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){return a=a<0?a+1:a>1?a-1:a,a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(Math.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();return e.s+=c.value/100,e.s=d(e.s),b(e)},desatura
te:function(a,c){var e=a.toHSL();return e.s-=c.value/100,e.s=d(e.s),b(e)},lighten:function(a,c){var e=a.toHSL();return e.l+=c.value/100,e.l=d(e.l),b(e)},darken:function(a,c){var e=a.toHSL();return e.l-=c.value/100,e.l=d(e.l),b(e)},fadein:function(a,c){var e=a.toHSL();return e.a+=c.value/100,e.a=d(e.a),b(e)},fadeout:function(a,c){var e=a.toHSL();return e.a-=c.value/100,e.a=d(e.a),b(e)},fade:function(a,c){var e=a.toHSL();return e.a=c.value/100,e.a=d(e.a),b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;return d.h=e<0?360+e:e,b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).repl
ace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e<c.length;e++)d=d.replace(/%[sda]/i,function(a){var b=a.match(/s/i)?c[e].value:c[e].toCSS();return a.match(/[A-Z]$/)?encodeURIComponent(b):b});return d=d.replace(/%%/g,"%"),new a.Quoted('"'+d+'"',d)},round:function(a){return this._math("round",a)},ceil:function(a){return this._math("ceil",a)},floor:function(a){return this._math("floor",a)},_math:function(b,d){if(d instanceof a.Dimension)return new a.Dimension(Math[b](c(d)),d.unit);if(typeof d=="number")return Math[b](d);throw{type:"Argument",message:"argument must be a number"}},argb:function(b){return new a.Anonymous(b.toARGB())},percentage:function(b){return new a.Dimension(b.val
ue*100,"%")},color:function(b){if(b instanceof a.Quoted)return new a.Color(b.value.slice(1));throw{type:"Argument",message:"argument must be a string"}},iscolor:function(b){return this._isa(b,a.Color)},isnumber:function(b){return this._isa(b,a.Dimension)},isstring:function(b){return this._isa(b,a.Quoted)},iskeyword:function(b){return this._isa(b,a.Keyword)},isurl:function(b){return this._isa(b,a.URL)},ispixel:function(b){return b instanceof a.Dimension&&b.unit==="px"?a.True:a.False},ispercentage:function(b){return b instanceof a.Dimension&&b.unit==="%"?a.True:a.False},isem:function(b){return b instanceof a.Dimension&&b.unit==="em"?a.True:a.False},_isa:function(b,c){return b instanceof c?a.True:a.False}}})(c("./tree")),function(a){a.colors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:&q
uot;#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquois
e:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3&qu
ot;,lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:&q
uot;#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080"
,thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"}}(c("./tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(a){return this.value.eval&&(this.value=this.value.eval(a)),this}}}(c("../tree")),function(a){a.Anonymous=function(a){this.value=a.value||a},a.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Assignment=function(a,b){this.key=a,this.value=b},a.Assignment.prototype={toCSS:function(){return this.key+"="+(this.value.toCSS?this.value.toCSS():this.value)},eval:function(a){return this.value.eval&&(this.value=this.v
alue.eval(a)),this}}}(c("../tree")),function(a){a.Call=function(a,b,c,d){this.name=a,this.args=b,this.index=c,this.filename=d},a.Call.prototype={eval:function(b){var c=this.args.map(function(a){return a.eval(b)});if(!(this.name in a.functions))return new a.Anonymous(this.name+"("+c.map(function(a){return a.toCSS()}).join(", ")+")");try{return a.functions[this.name].apply(a.functions,c)}catch(d){throw{type:d.type||"Runtime",message:"error evaluating function `"+this.name+"`"+(d.message?": "+d.message:""),index:this.index,filename:this.filename}}},toCSS:function(a){return this.eval(a).toCSS()}}}(c("../tree")),function(a){a.Color=function(a,b){Array.isArray(a)?this.rgb=a:a.length==6?this.rgb=a.match(/.{2}/g).map(function(a){return parseInt(a,16)}):this.rgb=a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha=typeof b=="number"?b:1},a.Color.prototype={eval:
function(){return this},toCSS:function(){return this.alpha<1?"rgba("+this.rgb.map(function(a){return Math.round(a)}).concat(this.alpha).join(", ")+")":"#"+this.rgb.map(function(a){return a=Math.round(a),a=(a>255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);switch(e){case a:g=(b-c)/j+(b<c?6:0);break;case b:g=(c-a)/j+2;break;case c:g=(a-b)/j+4}g/=6}return{h:g*360,s:h,l:i,a:d}},toARGB:function(){var a=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+a.map(function(a){return a=Math.round(a),a=(a>255?255:a<0?0:a).toString(
16),a.length===1?"0"+a:a}).join("")}}}(c("../tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Condition=function(a,b,c,d,e){this.op=a.trim(),this.lvalue=b,this.rvalue=c,this.index=d,this.negate=e},a.Condition.prototype.eval=function(a){var b=this.lvalue.eval(a),c=this.rvalue.eval(a),d=this.index,e,e=function(a){switch(a){case"and":return b&&c;case"or":return b||c;default:if(b.compare)e=b.compare(c);else if(c.compare)e=c.compare(b);else throw{type:"Type",message:"Unable to perform comparison",index:d};switch(e){case-1:return a==="<"||a==="=<";case 0:return a==="="||a===">="||a==="=<";case 1:return a===">"||a===">="}}}(this.op);return this.negate?!e
:e}}(c("../tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)},compare:function(b){return b instanceof a.Dimension?b.value>this.value?-1:b.value<this.value?1:0:-1}}}(c("../tree")),function(a){a.Directive=function(b,c,d){this.name=b,Array.isArray(c)?(this.ruleset=new a.Ruleset([],c),this.ruleset.allowImports=!0):this.value=c},a.Directive.prototype={toCSS:function(a,b){return this.ruleset?(this.ruleset.root=!0,this.name+(b.compress?"{":" {\n ")+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n ")+(b.compress?"}":"\n}\n")):this.name+" "+this.value.toCSS()+";\n"},eval:function(a){r
eturn a.frames.unshift(this),this.ruleset=this.ruleset&&this.ruleset.eval(a),a.frames.shift(),this},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(c("../tree")),function(a){a.Element=function(b,c,d){this.combinator=b instanceof a.Combinator?b:new a.Combinator(b),typeof c=="string"?this.value=c.trim():c?this.value=c:this.value="",this.index=d},a.Element.prototype.eval=function(b){return new a.Element(this.combinator,this.value.eval?this.value.eval(b):this.value,this.index)},a.Element.prototype.toCSS=function(a){return this.combinator.toCSS(a||{})+(this.value.toCSS?this.value.toCSS(a):this.value)},a.Combinator=function(a){a===" "?this.value=" ":a==="& "?this.value="& ":this.value=a?a.trim():""},a.Combina
tor.prototype.toCSS=function(a){return{"":""," ":" ","&":"","& ":" ",":":" :","+":a.compress?"+":" + ","~":a.compress?"~":" ~ ",">":a.compress?">":" > "}[this.value]}}(c("../tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS?b.toCSS(a):""}).join(" ")}}}(c("../tree")),function(a){a.Import=function(b,c,d,e){var f=this;this.index=e,this._path=b,this.features=d&&new a.Value(d),b instanceof a.Quoted?this.path=/\.(le?|c)ss(\?.*)?$/.test(b.value)?b.value:b.value+".less":this
.path=b.value.value||b.value,this.css=/css(\?.*)?$/.test(this.path),this.css||c.push(this.path,function(b,c){b&&(b.index=e),f.root=c||new a.Ruleset([],[])})},a.Import.prototype={toCSS:function(a){var b=this.features?" "+this.features.toCSS(a):"";return this.css?"@import "+this._path.toCSS()+b+";\n":""},eval:function(b){var c,d=this.features&&this.features.eval(b);if(this.css)return this;c=new a.Ruleset([],this.root.rules.slice(0));for(var e=0;e<c.rules.length;e++)c.rules[e]instanceof a.Import&&Array.prototype
+.splice.apply(c.rules,[e,1].concat(c.rules[e].eval(b)));return this.features?new a.Media(c.rules,this.features.value):c.rules}}}(c("../tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify((new a.Variable("@"+e,d.index)).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: `"+f+"`",index:this.index}}for(var h in b.frames[0].variables())e[h.slice(1)]={value:b.frames[0].variables()[h].value,toJS:function(){return this.value.eval(b).toCSS()}};try{c=f.call(e)}catch(g){throw{message:"JavaScript evaluation error: '"+g.name+": "+g.message+"'",index:this.index}}return typeof c=="string"?new a.Quoted('"'+c+'"',c,this.escaped,this.index):Array.isArray(c)?new a.Anonymo
us(c.join(", ")):new a.Anonymous(c)}}}(c("../tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value},compare:function(b){return b instanceof a.Keyword?b.value===this.value?0:1:-1}},a.True=new a.Keyword("true"),a.False=new a.Keyword("false")}(c("../tree")),function(a){a.Media=function(b,c){var d=new a.Element("&",null,0),e=[new a.Selector([d])];this.features=new a.Value(c),this.ruleset=new a.Ruleset(e,b),this.ruleset.allowImports=!0},a.Media.prototype={toCSS:function(a,b){var c=this.features.toCSS(b);return this.ruleset.root=a.length===0||a[0].multiMedia,"@media "+c+(b.compress?"{":" {\n ")+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n ")+(b.compress?"}":"\n}\n")},eval:function(b){b.mediaBlocks||(b.mediaBlocks=[],b.mediaPath=[]);var c=b.mediaBlocks.length;b.mediaPath.push(
this),b.mediaBlocks.push(this);var d=new a.Media([],[]);return d.features=this.features.eval(b),b.frames.unshift(this.ruleset),d.ruleset=this.ruleset.eval(b),b.frames.shift(),b.mediaBlocks[c]=d,b.mediaPath.pop(),b.mediaPath.length===0?d.evalTop(b):d.evalNested(b)},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.ruleset)},evalTop:function(b){var c=this;if(b.mediaBlocks.length>1){var d=new a.Element("&",null,0),e=[new a.Selector([d])];c=new a.Ruleset(e,b.mediaBlocks),c.multiMedia=!0}return delete b.mediaBlocks,delete b.mediaPath,c},evalNested:function(b){var c,d,e=b.mediaPath.concat([this]);for(c=0;c<e.length;c++)d=e[c].features instanceof a.Value?e[c].features.value:e[c].features,e[c]=Array.isArray(d)?d:[d];return this.features=new a.Value(this.permute(e).map(function(b){b=b.map(function(b)
{return b.toCSS?b:new a.Anonymous(b)});for(c=b.length-1;c>0;c--)b.splice(c,0,new a.Anonymous("and"));return new a.Expression(b)})),new a.Ruleset([],[])},permute:function(a){if(a.length===0)return[];if(a.length===1)return a[0];var b=[],c=this.permute(a.slice(1));for(var d=0;d<c.length;d++)for(var e=0;e<a[0].length;e++)b.push([a[0][e]].concat(c[d]));return b}}}(c("../tree")),function(a){a.mixin={},a.mixin.Call=function(b,c,d,e,f){this.selector=new a.Selector(b),this.arguments=c,this.index=d,this.filename=e,this.important=f},a.mixin.Call.prototype={eval:function(a){var b,c,d=[],e=!1;for(var f=0;f<a.frames.length;f++)if((b=a.frames[f].find(this.selector)).length>0){c=this.arguments&&this.arguments.map(function(b){return b.eval(a)});for(var g=0;g<b.length;g++)if(b[g].match(c,a))try{Array.prototype.push.apply(d,b[g].eval(a,this.arguments,this.important).rules),e=!0}catch(h){throw{message:h.message,index:this.index,filename:this.filename,stack:
h.stack}}if(e)return d;throw{type:"Runtime",message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(a){return a.toCSS()}).join(", ")+")`",index:this.index,filename:this.filename}}throw{type:"Name",message:this.selector.toCSS().trim()+" is undefined",index:this.index,filename:this.filename}}},a.mixin.Definition=function(b,c,d,e,f){this.name=b,this.selectors=[new a.Selector([new a.Element(null,b)])],this.params=c,this.condition=e,this.variadic=f,this.arity=c.length,this.rules=d,this._lookups={},this.required=c.reduce(function(a,b){return!b.name||b.name&&!b.value?a+1:a},0),this.parent=a.Ruleset.prototype,this.frames=[]},a.mixin.Definition.prototype={toCSS:function(){return""},variable:function(a){return this.parent.variable.call(this,a)},variables:function(){return this.parent.variables.call(this)},find:function(){return this.parent.find.apply(th
is,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},evalParams:function(b,c){var d=new a.Ruleset(null,[]),e;for(var f=0,g,h;f<this.params.length;f++)if(h=this.params[f].name)if(this.params[f].variadic&&c){e=[];for(var i=f;i<c.length;i++)e.push(c[i].eval(b));d.rules.unshift(new a.Rule(h,(new a.Expression(e)).eval(b)))}else if(g=c&&c[f]||this.params[f].value)d.rules.unshift(new a.Rule(h,g.eval(b)));else throw{type:"Runtime",message:"wrong number of arguments for "+this.name+" ("+c.length+" for "+this.arity+")"};return d},eval:function(b,c,d){var e=this.evalParams(b,c),f,g=[],h,i;for(var j=0;j<Math.max(this.params.length,c&&c.length);j++)g.push(c[j]||this.params[j].value);return e.rules.unshift(new a.Rule("@arguments",(new a.Expression(g)).eval(b))),h=d?this.rules.map(function(b){return new a.Rule(b.name,b.value,"!important",b.index)}):this.rules.slice(0),(new
a.Ruleset(null,h)).eval({frames:[this,e].concat(this.frames,b.frames)})},match:function(a,b){var c=a&&a.length||0,d,e;if(!this.variadic){if(c<this.required)return!1;if(c>this.params.length)return!1;if(this.required>0&&c>this.params.length)return!1}if(this.condition&&!this.condition.eval({frames:[this.evalParams(b,a)].concat(b.frames)}))return!1;d=Math.min(c,this.arity);for(var f=0;f<d;f++)if(!this.params[f].name&&a[f].eval(b).toCSS()!=this.params[f].value.eval(b).toCSS())return!1;return!0}}}(c("../tree")),function(a){a.Operation=function(a,b){this.op=a.trim(),this.operands=b},a.Operation.prototype.eval=function(b){var c=this.operands[0].eval(b),d=this.operands[1].eval(b),e;if(c instanceof a.Dimension&&d instanceof a.Color)if(this.op==="*"||this.op==="+")e=d,d=c,c=e;else throw{name:"OperationError",message:"Can't substract or divide a color from a number"};return c.operate(this.op
,d)},a.operate=function(a,b,c){switch(a){case"+":return b+c;case"-":return b-c;case"*":return b*c;case"/":return b/c}}}(c("../tree")),function(a){a.Paren=function(a){this.value=a},a.Paren.prototype={toCSS:function(a){return"("+this.value.toCSS(a)+")"},eval:function(b){return new a.Paren(this.value.eval(b))}}}(c("../tree")),function(a){a.Quoted=function(a,b,c,d){this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d},a.Quoted.prototype={toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(b){var c=this,d=this.value.replace(/`([^`]+)`/g,function(d,e){return(new a.JavaScript(e,c.index,!0)).eval(b).value}).replace(/@\{([\w-]+)\}/g,function(d,e){var f=(new a.Variable("@"+e,c.index)).eval(b);return"value"in f?f.value:f.toCSS()});return new a.Quoted(this.quote+d+this.quote,d,this.escaped,this.index)}}}(c("../tree")),
function(a){a.Rule=function(b,c,d,e,f){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.index=e,this.inline=f||!1,b.charAt(0)==="@"?this.variable=!0:this.variable=!1},a.Rule.prototype.toCSS=function(a){return this.variable?"":this.name+(a.compress?":":": ")+this.value.toCSS(a)+this.important+(this.inline?"":";")},a.Rule.prototype.eval=function(b){return new a.Rule(this.name,this.value.eval(b),this.important,this.index,this.inline)},a.Shorthand=function(a,b){this.a=a,this.b=b},a.Shorthand.prototype={toCSS:function(a){return this.a.toCSS(a)+"/"+this.b.toCSS(a)},eval:function(){return this}}}(c("../tree")),function(a){a.Ruleset=function(a,b,c){this.selectors=a,this.rules=b,this._lookups={},this.strictImports=c},a.Ruleset.prototype={eval:function(b){var c=this.selectors&&this.selectors.map(function(a){return a.eval(b)}),d=new a.R
uleset(c,this.rules.slice(0),this.strictImports);d.root=this.root,d.allowImports=this.allowImports,b.frames.unshift(d);if(d.root||d.allowImports||!d.strictImports)for(var e=0;e<d.rules.length;e++)d.rules[e]instanceof a.Import&&Array.prototype.splice.apply(d.rules,[e,1].concat(d.rules[e].eval(b)));for(var e=0;e<d.rules.length;e++)d.rules[e]instanceof a.mixin.Definition&&(d.rules[e].frames=b.frames.slice(0));for(var e=0;e<d.rules.length;e++)d.rules[e]instanceof a.mixin.Call&&Array.prototype.splice.apply(d.rules,[e,1].concat(d.rules[e].eval(b)));for(var e=0,f;e<d.rules.length;e++)f=d.rules[e],f instanceof a.mixin.Definition||(d.rules[e]=f.eval?f.eval(b):f);return b.frames.shift(),d},match:function(a){return!a||a.length===0},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(b,c){return c instanceof a.Rule&&c.variable===!0&&(b[c.name]=c),b},{})},variable:function(a){return this.variab
les()[a]},rulesets:function(){return this._rulesets?this._rulesets:this._rulesets=this.rules.filter(function(b){return b instanceof a.Ruleset||b instanceof a.mixin.Definition})},find:function(b,c){c=c||this;var d=[],e,f,g=b.toCSS();return g in this._lookups?this._lookups[g]:(this.rulesets().forEach(function(e){if(e!==c)for(var g=0;g<e.selectors.length;g++)if(f=b.match(e.selectors[g])){b.elements.length>e.selectors[g].elements.length?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}}),this._lookups[g]=d)},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;this.root||(b.length===0?g=this.selectors.map(function(a){return[a]}):this.joinSelectors(g,b,this.selectors));for(var j=0;j<this.rules.length;j++)i=this.rules[j],i.rules||i instanceof a.Directive||i instanceof a.Media?f.push(i.toCSS(g,c)):i instanceof a.Comment?i.silent||(this.root?f.push(i.toCSS(c)):e.push(i.toCSS(c))):i.toCSS&&!i.variable?e.push(i.toCSS(c)):i.value&&
!i.variable&&e.push(i.value.toString());return f=f.join(""),this.root?d.push(e.join(c.compress?"":"\n")):e.length>0&&(h=g.map(function(a){return a.map(function(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":",\n"),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f),d.join("")+(c.compress?"\n":"")},joinSelectors:function(a,b,c){for(var d=0;d<c.length;d++)this.joinSelector(a,b,c[d])},joinSelector:function(b,c,d){var e=[],f=[],g=[],h=[],i=!1,j;for(var k=0;k<d.elements.length;k++)j=d.elements[k],j.combinator.value.charAt(0)==="&"&&(i=!0),i?h.push(j):g.push(j);i||(h=g,g=[]),g.length>0&&e.push(new a.Selector(g)),h.length>0&&f.push(new a.Selector(h));for(var l=0;l<c.length;l++)b.push(e.concat(c[l]).concat(f))}
}}(c("../tree")),function(a){a.Selector=function(a){this.elements=a,this.elements[0].combinator.value===""&&(this.elements[0].combinator.value=" ")},a.Selector.prototype.match=function(a){var b=this.elements.length,c=a.elements.length,d=Math.min(b,c);if(b<c)return!1;for(var e=0;e<d;e++)if(this.elements[e].value!==a.elements[e].value)return!1;return!0},a.Selector.prototype.eval=function(b){return new a.Selector(this.elements.map(function(a){return a.eval(b)}))},a.Selector.prototype.toCSS=function(a){return this._css?this._css:this._css=this.elements.map(function(b){return typeof b=="string"?" "+b.trim():b.toCSS(a)}).join("")}}(c("../tree")),function(b){b.URL=function(b,c){b.data?this.attrs=b:(typeof a!="undefined"&&!/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(b.value)&&c.length>0&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value
=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("../tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("../tree")),function(a){a.Variable=function(a,b,c){this.name=a,this.index=b,this.file=c},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))retu
rn c;throw{type:"Name",message:"variable "+e+" is undefined",filename:this.file,index:this.index}}}}(c("../tree")),function(a){a.find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null},a.jsify=function(a){return Array.isArray(a.value)&&a.value.length>1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)}}(c("./tree"));var f=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||f?"development":"production"),d.async=!1,d.poll=d.poll||(f?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},
d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&m(function(a,b,c,d,e){b&&p(b.toCSS(),d,e.lastModified)})},d.poll)):d.optimization=3;var g;try{g=typeof a.localStorage=="undefined"?null:a.localStorage}catch(h){g=null}var i=document.getElementsByTagName("link"),j=/^text\/(x-)?less$/;d.sheets=[];for(var k=0;k<i.length;k++)(i[k].rel==="stylesheet/less"||i[k].rel.match(/stylesheet/)&&i[k].type.match(j))&&d.sheets.push(i[k]);d.refresh=function(a){var b,c;b=c=new Date,m(function(a,d,e,f,g){g.local?t("loading "+f.href+" from cache."):(t("parsed "+f.href+" successfully."),p(d.toCSS(),f,g.lastModified)),t("css for "+f.href+" generated in "+(new Date-c)+"ms"),g.remaining===0&&t("css generated in "+(new Date-b)+"ms"),c=new Date},a),l()},d
.refreshStyles=l,d.refresh(d.env==="development")})(window);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless130ejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0e.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0e.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0e.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4017 @@
</span><ins>+//
+// LESS - Leaner CSS v1.3.0
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+ return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+ // Rhino
+ // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+ if (typeof(window) === 'undefined') { less = {} }
+ else { less = window.less = {} }
+ tree = less.tree = {};
+ less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+ // Node.js
+ less = exports,
+ tree = require('./tree');
+ less.mode = 'node';
+} else {
+ // Browser
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+ less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // Top parser on an import tree must be sure there is one "env"
+ // which will then be passed arround by reference.
+ var env = env || { };
+ if (!env.contents) { env.contents={}; } // env.contents must be passed arround with top env
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ contents: env.contents, // Holds the imported file contents
+ mime: env && env.mime, // MIME type of .less files
+ error: null, // Error in parsing/evaluating an import
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (e, root) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+
+ var imported = path in that.files;
+
+ that.files[path] = root; // Store the root
+
+ if (e && !that.error) { that.error = e }
+
+ callback(e, root, imported);
+
+ if (that.queue.length === 0) { finish(e) } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ function isWhitespace(c) {
+ // Could change to \s?
+ var code = c.charCodeAt(0);
+ return code === 32 || code === 10 || code === 9;
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, index, k;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ skipWhitespace(length);
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ function skipWhitespace(length) {
+ var oldi = i, oldj = j,
+ endIndex = i + chunks[j].length,
+ mem = i += length;
+
+ while (i < endIndex) {
+ if (! isWhitespace(input.charAt(i))) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ return oldi !== i || oldj !== j;
+ }
+
+ function expect(arg, msg) {
+ var result = $(arg);
+ if (! result) {
+ error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+ : "unexpected token"));
+ } else {
+ return result;
+ }
+ }
+
+ function error(msg, type) {
+ throw { index: i, type: type || 'Syntax', message: msg };
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ function getInput(e, env) {
+ if (e.filename && env.filename && (e.filename !== env.filename)) {
+ return parser.imports.contents[e.filename];
+ } else {
+ return input;
+ }
+ }
+
+ function getLocation(index, input) {
+ for (var n = index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ return { line: typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+ column: column };
+ }
+
+ function getFileName(e) {
+ if(less.mode === 'browser' || less.mode === 'rhino')
+ return e.filename;
+ else
+ return require('path').resolve(e.filename);
+ }
+
+ function getDebugInfo(index, inputStream, e) {
+ return {
+ lineNumber: getLocation(index, inputStream).line + 1,
+ fileName: getFileName(e)
+ };
+ }
+
+ function LessError(e, env) {
+ var input = getInput(e, env),
+ loc = getLocation(e.index, input),
+ line = loc.line,
+ col = loc.column,
+ lines = input.split('\n');
+
+ this.type = e.type || 'Syntax';
+ this.message = e.message;
+ this.filename = e.filename || env.filename;
+ this.index = e.index;
+ this.line = typeof(line) === 'number' ? line + 1 : null;
+ this.callLine = e.call && (getLocation(e.call, input).line + 1);
+ this.callExtract = lines[getLocation(e.call, input).line];
+ this.stack = e.stack;
+ this.column = col;
+ this.extract = [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ];
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ input = str.replace(/\r\n/g, '\n');
+
+ // Remove potential UTF Byte Order Mark
+ input = input.replace(/^\uFEFF/, '');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = string.lastIndex = i;
+
+ if (match = string.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+
+ if (!inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ switch (c) {
+ case '{': if (! inParam) { level ++; chunk.push(c); break }
+ case '}': if (! inParam) { level --; chunk.push(c); chunks[++j] = chunk = []; break }
+ case '(': if (! inParam) { inParam = true; chunk.push(c); break }
+ case ')': if ( inParam) { inParam = false; chunk.push(c); break }
+ default: chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ error = new(LessError)({
+ index: i,
+ type: 'Parse',
+ message: "missing closing `}`",
+ filename: env.filename
+ }, env);
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ if (error) {
+ return callback(error);
+ }
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ try {
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+ } catch (e) {
+ return callback(new(LessError)(e, env));
+ }
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [], importError;
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false, dumpLineNumbers: env.dumpLineNumbers });
+ } catch (e) {
+ throw new(LessError)(e, env);
+ }
+
+ if ((importError = parser.imports.error)) { // Check if there was an error during importing
+ if (importError instanceof LessError) throw importError;
+ else throw new(LessError)(importError, env);
+ }
+
+ if (options.yuicompress && less.mode === 'node') {
+ return require('./cssmin').compressor.cssmin(css);
+ } else if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ type: "Parse",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function (e) {
+ if (e) callback(e);
+ else callback(null, root);
+ };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+
+ if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+ if (tree.colors.hasOwnProperty(k)) {
+ // detect named color
+ return new(tree.Color)(tree.colors[k].slice(1));
+ } else {
+ return new(tree.Keyword)(k);
+ }
+ }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, nameLC, args, alpha_ret, index = i;
+
+ if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+ name = name[1];
+ nameLC = name.toLowerCase();
+
+ if (nameLC === 'url') { return null }
+ else { i += name.length }
+
+ if (nameLC === 'alpha') {
+ alpha_ret = $(this.alpha);
+ if(typeof alpha_ret !== 'undefined') {
+ return alpha_ret;
+ }
+ }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args, index, env.filename) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.entities.assignment) || $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.ratio) ||
+ $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ // Assignments are argument entities for calls.
+ // They are present in ie filter properties as shown below.
+ //
+ // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+ //
+
+ assignment: function () {
+ var key, value;
+ if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+ return new(tree.Assignment)(key, value);
+ }
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || "";
+
+ expect(')');
+
+ return new(tree.URL)((value.value != null || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index, env.filename);
+ }
+ },
+
+ // A variable entity useing the protective {} e.g. @{var}
+ variableCurly: function () {
+ var name, curly, index = i;
+
+ if (input.charAt(i) === '@' && (curly = $(/^@\{([\w-]+)\}/))) {
+ return new(tree.Variable)("@" + curly[1], index, env.filename);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn|dpi|dpcm|dppx|rem|vw|vh|vmin|vm|ch)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // A Ratio
+ //
+ // 16/9
+ //
+ ratio: function () {
+ var value, c = input.charCodeAt(i);
+ if (c > 57 || c < 48) return;
+
+ if (value = $(/^(\d+\/\d+)/)) {
+ return new(tree.Ratio)(value[1]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ save();
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+
+ restore();
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args = [], arg, index = i, s = input.charAt(i), name, value, important = false;
+
+ if (s !== '.' && s !== '#') { return }
+
+ save(); // stop us absorbing part of an invalid selector
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e, i));
+ c = $('>');
+ }
+ if ($('(')) {
+ while (arg = $(this.expression)) {
+ value = arg;
+ name = null;
+
+ // Variable
+ if (arg.value.length == 1) {
+ var val = arg.value[0];
+ if (val instanceof tree.Variable) {
+ if ($(':')) {
+ if (value = $(this.expression)) {
+ name = val.name;
+ } else {
+ throw new(Error)("Expected value");
+ }
+ }
+ }
+ }
+
+ args.push({ name: name, value: value });
+
+ if (! $(',')) { break }
+ }
+ if (! $(')')) throw new(Error)("Expected )");
+ }
+
+ if ($(this.important)) {
+ important = true;
+ }
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+ }
+
+ restore();
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value, cond, variadic = false;
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ save();
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ do {
+ if (input.charAt(i) === '.' && $(/^\.{3}/)) {
+ variadic = true;
+ break;
+ } else if (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ value = expect(this.expression, 'expected expression');
+ params.push({ name: param.name, value: value });
+ } else if ($(/^\.{3}/)) {
+ params.push({ name: param.name, variadic: true });
+ variadic = true;
+ break;
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ } else {
+ break;
+ }
+ } while ($(','))
+
+ // .mixincall("@{a}");
+ // looks a bit like a mixin definition.. so we have to be nice and restore
+ if (!$(')')) {
+ furthest = i;
+ restore();
+ }
+
+ if ($(/^when/)) { // Guard
+ cond = expect(this.conditions, 'expected condition');
+ }
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
+ } else {
+ restore();
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^\(opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ expect(')');
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c, v;
+
+ c = $(this.combinator);
+
+ e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
+ $('*') || $('&') || $(this.attribute) || $(/^\([^)@]+\)/) || $(/^[\.#](?=@)/) || $(this.entities.variableCurly);
+
+ if (! e) {
+ if ($('(') && (v = ($(this.entities.variableCurly) || $(this.entities.variable))) && $(')')) {
+ e = new(tree.Paren)(v);
+ }
+ }
+
+ if (e) { return new(tree.Element)(c, e, i) }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i).match(/\s/)) { i++ }
+ return new(tree.Combinator)(c);
+ } else if (input.charAt(i - 1).match(/\s/)) {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ // depreciated, will be removed soon
+ if ($('(')) {
+ sel = $(this.entity);
+ expect(')');
+ return new(tree.Selector)([new(tree.Element)('', sel, i)]);
+ }
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[A-Za-z][A-Za-z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^(?:[_A-Za-z0-9-]|\\.)+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match, debugInfo;
+ save();
+
+ if (env.dumpLineNumbers)
+ debugInfo = getDebugInfo(i, input, env);
+
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports);
+ if (env.dumpLineNumbers)
+ ruleset.debugInfo = debugInfo;
+ return ruleset;
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path, features, index = i;
+
+ save();
+
+ var dir = $(/^@import(?:-(once))?\s+/);
+
+ if (dir && (path = $(this.entities.quoted) || $(this.entities.url))) {
+ features = $(this.mediaFeatures);
+ if ($(';')) {
+ return new(tree.Import)(path, imports, features, (dir[1] === 'once'), index);
+ }
+ }
+
+ restore();
+ },
+
+ mediaFeature: function () {
+ var e, p, nodes = [];
+
+ do {
+ if (e = $(this.entities.keyword)) {
+ nodes.push(e);
+ } else if ($('(')) {
+ p = $(this.property);
+ e = $(this.entity);
+ if ($(')')) {
+ if (p && e) {
+ nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+ } else if (e) {
+ nodes.push(new(tree.Paren)(e));
+ } else {
+ return null;
+ }
+ } else { return null }
+ }
+ } while (e);
+
+ if (nodes.length > 0) {
+ return new(tree.Expression)(nodes);
+ }
+ },
+
+ mediaFeatures: function () {
+ var e, features = [];
+
+ do {
+ if (e = $(this.mediaFeature)) {
+ features.push(e);
+ if (! $(',')) { break }
+ } else if (e = $(this.entities.variable)) {
+ features.push(e);
+ if (! $(',')) { break }
+ }
+ } while (e);
+
+ return features.length > 0 ? features : null;
+ },
+
+ media: function () {
+ var features, rules, media, debugInfo;
+
+ if (env.dumpLineNumbers)
+ debugInfo = getDebugInfo(i, input, env);
+
+ if ($(/^@media/)) {
+ features = $(this.mediaFeatures);
+
+ if (rules = $(this.block)) {
+ media = new(tree.Media)(rules, features);
+ if(env.dumpLineNumbers)
+ media.debugInfo = debugInfo;
+ return media;
+ }
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, identifier, e, nodes, nonVendorSpecificName,
+ hasBlock, hasIdentifier;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import']) || $(this.media)) {
+ return value;
+ }
+
+ save();
+
+ name = $(/^@[a-z-]+/);
+
+ nonVendorSpecificName = name;
+ if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
+ nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1);
+ }
+
+ switch(nonVendorSpecificName) {
+ case "@font-face":
+ hasBlock = true;
+ break;
+ case "@viewport":
+ case "@top-left":
+ case "@top-left-corner":
+ case "@top-center":
+ case "@top-right":
+ case "@top-right-corner":
+ case "@bottom-left":
+ case "@bottom-left-corner":
+ case "@bottom-center":
+ case "@bottom-right":
+ case "@bottom-right-corner":
+ case "@left-top":
+ case "@left-middle":
+ case "@left-bottom":
+ case "@right-top":
+ case "@right-middle":
+ case "@right-bottom":
+ hasBlock = true;
+ break;
+ case "@page":
+ case "@document":
+ case "@supports":
+ case "@keyframes":
+ hasBlock = true;
+ hasIdentifier = true;
+ break;
+ }
+
+ if (hasIdentifier) {
+ name += " " + ($(/^[^{]+/) || '').trim();
+ }
+
+ if (hasBlock)
+ {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else {
+ if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+
+ restore();
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (!isWhitespace(input.charAt(i - 1)) && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ conditions: function () {
+ var a, b, index = i, condition;
+
+ if (a = $(this.condition)) {
+ while ($(',') && (b = $(this.condition))) {
+ condition = new(tree.Condition)('or', condition || a, b, index);
+ }
+ return condition || a;
+ }
+ },
+ condition: function () {
+ var a, b, c, op, index = i, negate = false;
+
+ if ($(/^not/)) { negate = true }
+ expect('(');
+ if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+ if (op = $(/^(?:>=|=<|[<=>])/)) {
+ if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+ c = new(tree.Condition)(op, a, b, index, negate);
+ } else {
+ error('expected expression');
+ }
+ } else {
+ c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+ }
+ expect(')');
+ return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[_a-z0-9-]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (!/^([a-z-]+:)?\//.test(path) && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ // __ Now using the hack of passing a ref to top parser's content cache in the 1st arg. __
+ loadStyleSheet({ href: path, title: path, type: env.mime, contents: env.contents }, function (e) {
+ if (e && typeof(env.errback) === "function") {
+ env.errback.call(null, path, paths, callback, env);
+ } else {
+ callback.apply(null, arguments);
+ }
+ }, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ red: function (color) {
+ return new(tree.Dimension)(color.rgb[0]);
+ },
+ green: function (color) {
+ return new(tree.Dimension)(color.rgb[1]);
+ },
+ blue: function (color) {
+ return new(tree.Dimension)(color.rgb[2]);
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ luma: function (color) {
+ return new(tree.Dimension)(Math.round((0.2126 * (color.rgb[0]/255) +
+ 0.7152 * (color.rgb[1]/255) +
+ 0.0722 * (color.rgb[2]/255))
+ * color.alpha * 100), '%');
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fade: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a = amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ if (!weight) {
+ weight = new(tree.Dimension)(50);
+ }
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ contrast: function (color, dark, light, threshold) {
+ if (typeof light === 'undefined') {
+ light = this.rgba(255, 255, 255, 1.0);
+ }
+ if (typeof dark === 'undefined') {
+ dark = this.rgba(0, 0, 0, 1.0);
+ }
+ if (typeof threshold === 'undefined') {
+ threshold = 0.43;
+ } else {
+ threshold = threshold.value;
+ }
+ if (((0.2126 * (color.rgb[0]/255) + 0.7152 * (color.rgb[1]/255) + 0.0722 * (color.rgb[2]/255)) * color.alpha) < threshold) {
+ return light;
+ } else {
+ return dark;
+ }
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n, f) {
+ var fraction = typeof(f) === "undefined" ? 0 : f.value;
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(number(n).toFixed(fraction), n.unit);
+ } else if (typeof(n) === 'number') {
+ return n.toFixed(fraction);
+ } else {
+ throw { type: "Argument", message: "argument must be a number" };
+ }
+ },
+ ceil: function (n) {
+ return this._math('ceil', n);
+ },
+ floor: function (n) {
+ return this._math('floor', n);
+ },
+ _math: function (fn, n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math[fn](n);
+ } else {
+ throw { type: "Argument", message: "argument must be a number" };
+ }
+ },
+ argb: function (color) {
+ return new(tree.Anonymous)(color.toARGB());
+
+ },
+ percentage: function (n) {
+ return new(tree.Dimension)(n.value * 100, '%');
+ },
+ color: function (n) {
+ if (n instanceof tree.Quoted) {
+ return new(tree.Color)(n.value.slice(1));
+ } else {
+ throw { type: "Argument", message: "argument must be a string" };
+ }
+ },
+ iscolor: function (n) {
+ return this._isa(n, tree.Color);
+ },
+ isnumber: function (n) {
+ return this._isa(n, tree.Dimension);
+ },
+ isstring: function (n) {
+ return this._isa(n, tree.Quoted);
+ },
+ iskeyword: function (n) {
+ return this._isa(n, tree.Keyword);
+ },
+ isurl: function (n) {
+ return this._isa(n, tree.URL);
+ },
+ ispixel: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+ },
+ ispercentage: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+ },
+ isem: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+ },
+ _isa: function (n, Type) {
+ return (n instanceof Type) ? tree.True : tree.False;
+ },
+
+ /* Blending modes */
+
+ multiply: function(color1, color2) {
+ var r = color1.rgb[0] * color2.rgb[0] / 255;
+ var g = color1.rgb[1] * color2.rgb[1] / 255;
+ var b = color1.rgb[2] * color2.rgb[2] / 255;
+ return this.rgb(r, g, b);
+ },
+ screen: function(color1, color2) {
+ var r = 255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+ var g = 255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+ var b = 255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+ return this.rgb(r, g, b);
+ },
+ overlay: function(color1, color2) {
+ var r = color1.rgb[0] < 128 ? 2 * color1.rgb[0] * color2.rgb[0] / 255 : 255 - 2 * (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+ var g = color1.rgb[1] < 128 ? 2 * color1.rgb[1] * color2.rgb[1] / 255 : 255 - 2 * (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+ var b = color1.rgb[2] < 128 ? 2 * color1.rgb[2] * color2.rgb[2] / 255 : 255 - 2 * (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+ return this.rgb(r, g, b);
+ },
+ softlight: function(color1, color2) {
+ var t = color2.rgb[0] * color1.rgb[0] / 255;
+ var r = t + color1.rgb[0] * (255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255 - t) / 255;
+ t = color2.rgb[1] * color1.rgb[1] / 255;
+ var g = t + color1.rgb[1] * (255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255 - t) / 255;
+ t = color2.rgb[2] * color1.rgb[2] / 255;
+ var b = t + color1.rgb[2] * (255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255 - t) / 255;
+ return this.rgb(r, g, b);
+ },
+ hardlight: function(color1, color2) {
+ var r = color2.rgb[0] < 128 ? 2 * color2.rgb[0] * color1.rgb[0] / 255 : 255 - 2 * (255 - color2.rgb[0]) * (255 - color1.rgb[0]) / 255;
+ var g = color2.rgb[1] < 128 ? 2 * color2.rgb[1] * color1.rgb[1] / 255 : 255 - 2 * (255 - color2.rgb[1]) * (255 - color1.rgb[1]) / 255;
+ var b = color2.rgb[2] < 128 ? 2 * color2.rgb[2] * color1.rgb[2] / 255 : 255 - 2 * (255 - color2.rgb[2]) * (255 - color1.rgb[2]) / 255;
+ return this.rgb(r, g, b);
+ },
+ difference: function(color1, color2) {
+ var r = Math.abs(color1.rgb[0] - color2.rgb[0]);
+ var g = Math.abs(color1.rgb[1] - color2.rgb[1]);
+ var b = Math.abs(color1.rgb[2] - color2.rgb[2]);
+ return this.rgb(r, g, b);
+ },
+ exclusion: function(color1, color2) {
+ var r = color1.rgb[0] + color2.rgb[0] * (255 - color1.rgb[0] - color1.rgb[0]) / 255;
+ var g = color1.rgb[1] + color2.rgb[1] * (255 - color1.rgb[1] - color1.rgb[1]) / 255;
+ var b = color1.rgb[2] + color2.rgb[2] * (255 - color1.rgb[2] - color1.rgb[2]) / 255;
+ return this.rgb(r, g, b);
+ },
+ average: function(color1, color2) {
+ var r = (color1.rgb[0] + color2.rgb[0]) / 2;
+ var g = (color1.rgb[1] + color2.rgb[1]) / 2;
+ var b = (color1.rgb[2] + color2.rgb[2]) / 2;
+ return this.rgb(r, g, b);
+ },
+ negation: function(color1, color2) {
+ var r = 255 - Math.abs(255 - color2.rgb[0] - color1.rgb[0]);
+ var g = 255 - Math.abs(255 - color2.rgb[1] - color1.rgb[1]);
+ var b = 255 - Math.abs(255 - color2.rgb[2] - color1.rgb[2]);
+ return this.rgb(r, g, b);
+ },
+ tint: function(color, amount) {
+ return this.mix(this.rgb(255,255,255), color, amount);
+ },
+ shade: function(color, amount) {
+ return this.mix(this.rgb(0, 0, 0), color, amount);
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+ tree.colors = {
+ 'aliceblue':'#f0f8ff',
+ 'antiquewhite':'#faebd7',
+ 'aqua':'#00ffff',
+ 'aquamarine':'#7fffd4',
+ 'azure':'#f0ffff',
+ 'beige':'#f5f5dc',
+ 'bisque':'#ffe4c4',
+ 'black':'#000000',
+ 'blanchedalmond':'#ffebcd',
+ 'blue':'#0000ff',
+ 'blueviolet':'#8a2be2',
+ 'brown':'#a52a2a',
+ 'burlywood':'#deb887',
+ 'cadetblue':'#5f9ea0',
+ 'chartreuse':'#7fff00',
+ 'chocolate':'#d2691e',
+ 'coral':'#ff7f50',
+ 'cornflowerblue':'#6495ed',
+ 'cornsilk':'#fff8dc',
+ 'crimson':'#dc143c',
+ 'cyan':'#00ffff',
+ 'darkblue':'#00008b',
+ 'darkcyan':'#008b8b',
+ 'darkgoldenrod':'#b8860b',
+ 'darkgray':'#a9a9a9',
+ 'darkgrey':'#a9a9a9',
+ 'darkgreen':'#006400',
+ 'darkkhaki':'#bdb76b',
+ 'darkmagenta':'#8b008b',
+ 'darkolivegreen':'#556b2f',
+ 'darkorange':'#ff8c00',
+ 'darkorchid':'#9932cc',
+ 'darkred':'#8b0000',
+ 'darksalmon':'#e9967a',
+ 'darkseagreen':'#8fbc8f',
+ 'darkslateblue':'#483d8b',
+ 'darkslategray':'#2f4f4f',
+ 'darkslategrey':'#2f4f4f',
+ 'darkturquoise':'#00ced1',
+ 'darkviolet':'#9400d3',
+ 'deeppink':'#ff1493',
+ 'deepskyblue':'#00bfff',
+ 'dimgray':'#696969',
+ 'dimgrey':'#696969',
+ 'dodgerblue':'#1e90ff',
+ 'firebrick':'#b22222',
+ 'floralwhite':'#fffaf0',
+ 'forestgreen':'#228b22',
+ 'fuchsia':'#ff00ff',
+ 'gainsboro':'#dcdcdc',
+ 'ghostwhite':'#f8f8ff',
+ 'gold':'#ffd700',
+ 'goldenrod':'#daa520',
+ 'gray':'#808080',
+ 'grey':'#808080',
+ 'green':'#008000',
+ 'greenyellow':'#adff2f',
+ 'honeydew':'#f0fff0',
+ 'hotpink':'#ff69b4',
+ 'indianred':'#cd5c5c',
+ 'indigo':'#4b0082',
+ 'ivory':'#fffff0',
+ 'khaki':'#f0e68c',
+ 'lavender':'#e6e6fa',
+ 'lavenderblush':'#fff0f5',
+ 'lawngreen':'#7cfc00',
+ 'lemonchiffon':'#fffacd',
+ 'lightblue':'#add8e6',
+ 'lightcoral':'#f08080',
+ 'lightcyan':'#e0ffff',
+ 'lightgoldenrodyellow':'#fafad2',
+ 'lightgray':'#d3d3d3',
+ 'lightgrey':'#d3d3d3',
+ 'lightgreen':'#90ee90',
+ 'lightpink':'#ffb6c1',
+ 'lightsalmon':'#ffa07a',
+ 'lightseagreen':'#20b2aa',
+ 'lightskyblue':'#87cefa',
+ 'lightslategray':'#778899',
+ 'lightslategrey':'#778899',
+ 'lightsteelblue':'#b0c4de',
+ 'lightyellow':'#ffffe0',
+ 'lime':'#00ff00',
+ 'limegreen':'#32cd32',
+ 'linen':'#faf0e6',
+ 'magenta':'#ff00ff',
+ 'maroon':'#800000',
+ 'mediumaquamarine':'#66cdaa',
+ 'mediumblue':'#0000cd',
+ 'mediumorchid':'#ba55d3',
+ 'mediumpurple':'#9370d8',
+ 'mediumseagreen':'#3cb371',
+ 'mediumslateblue':'#7b68ee',
+ 'mediumspringgreen':'#00fa9a',
+ 'mediumturquoise':'#48d1cc',
+ 'mediumvioletred':'#c71585',
+ 'midnightblue':'#191970',
+ 'mintcream':'#f5fffa',
+ 'mistyrose':'#ffe4e1',
+ 'moccasin':'#ffe4b5',
+ 'navajowhite':'#ffdead',
+ 'navy':'#000080',
+ 'oldlace':'#fdf5e6',
+ 'olive':'#808000',
+ 'olivedrab':'#6b8e23',
+ 'orange':'#ffa500',
+ 'orangered':'#ff4500',
+ 'orchid':'#da70d6',
+ 'palegoldenrod':'#eee8aa',
+ 'palegreen':'#98fb98',
+ 'paleturquoise':'#afeeee',
+ 'palevioletred':'#d87093',
+ 'papayawhip':'#ffefd5',
+ 'peachpuff':'#ffdab9',
+ 'peru':'#cd853f',
+ 'pink':'#ffc0cb',
+ 'plum':'#dda0dd',
+ 'powderblue':'#b0e0e6',
+ 'purple':'#800080',
+ 'red':'#ff0000',
+ 'rosybrown':'#bc8f8f',
+ 'royalblue':'#4169e1',
+ 'saddlebrown':'#8b4513',
+ 'salmon':'#fa8072',
+ 'sandybrown':'#f4a460',
+ 'seagreen':'#2e8b57',
+ 'seashell':'#fff5ee',
+ 'sienna':'#a0522d',
+ 'silver':'#c0c0c0',
+ 'skyblue':'#87ceeb',
+ 'slateblue':'#6a5acd',
+ 'slategray':'#708090',
+ 'slategrey':'#708090',
+ 'snow':'#fffafa',
+ 'springgreen':'#00ff7f',
+ 'steelblue':'#4682b4',
+ 'tan':'#d2b48c',
+ 'teal':'#008080',
+ 'thistle':'#d8bfd8',
+ 'tomato':'#ff6347',
+ // 'transparent':'rgba(0,0,0,0)',
+ 'turquoise':'#40e0d0',
+ 'violet':'#ee82ee',
+ 'wheat':'#f5deb3',
+ 'white':'#ffffff',
+ 'whitesmoke':'#f5f5f5',
+ 'yellow':'#ffff00',
+ 'yellowgreen':'#9acd32'
+ };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this },
+ compare: function (x) {
+ if (!x.toCSS) {
+ return -1;
+ }
+
+ var left = this.toCSS(),
+ right = x.toCSS();
+
+ if (left === right) {
+ return 0;
+ }
+
+ return left < right ? -1 : 1;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+ this.key = key;
+ this.value = val;
+};
+tree.Assignment.prototype = {
+ toCSS: function () {
+ return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+ },
+ eval: function (env) {
+ if (this.value.eval) {
+ return new(tree.Assignment)(this.key, this.value.eval(env));
+ }
+ return this;
+ }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+ this.name = name;
+ this.args = args;
+ this.index = index;
+ this.filename = filename;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ try {
+ return tree.functions[this.name].apply(tree.functions, args);
+ } catch (e) {
+ throw { type: e.type || "Runtime",
+ message: "error evaluating function `" + this.name + "`" +
+ (e.message ? ': ' + e.message : ''),
+ index: this.index, filename: this.filename };
+ }
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS(env) }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ },
+ toARGB: function () {
+ var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+ return '#' + argb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ },
+ compare: function (x) {
+ if (!x.rgb) {
+ return -1;
+ }
+
+ return (x.rgb[0] === this.rgb[0] &&
+ x.rgb[1] === this.rgb[1] &&
+ x.rgb[2] === this.rgb[2] &&
+ x.alpha === this.alpha) ? 0 : -1;
+ }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+ this.op = op.trim();
+ this.lvalue = l;
+ this.rvalue = r;
+ this.index = i;
+ this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+ var a = this.lvalue.eval(env),
+ b = this.rvalue.eval(env);
+
+ var i = this.index, result;
+
+ var result = (function (op) {
+ switch (op) {
+ case 'and':
+ return a && b;
+ case 'or':
+ return a || b;
+ default:
+ if (a.compare) {
+ result = a.compare(b);
+ } else if (b.compare) {
+ result = b.compare(a);
+ } else {
+ throw { type: "Type",
+ message: "Unable to perform comparison",
+ index: i };
+ }
+ switch (result) {
+ case -1: return op === '<' || op === '=<';
+ case 0: return op === '=' || op === '>=' || op === '=<';
+ case 1: return op === '>' || op === '>=';
+ }
+ }
+ })(this.op);
+ return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ },
+
+ // TODO: Perform unit conversion before comparing
+ compare: function (other) {
+ if (other instanceof tree.Dimension) {
+ if (other.value > this.value) {
+ return -1;
+ } else if (other.value < this.value) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ return -1;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+ this.name = name;
+
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ this.ruleset.allowImports = true;
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ var evaldDirective = this;
+ if (this.ruleset) {
+ env.frames.unshift(this);
+ evaldDirective = new(tree.Directive)(this.name);
+ evaldDirective.ruleset = this.ruleset.eval(env);
+ env.frames.shift();
+ }
+ return evaldDirective;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+
+ if (typeof(value) === 'string') {
+ this.value = value.trim();
+ } else if (value) {
+ this.value = value;
+ } else {
+ this.value = "";
+ }
+ this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+ return new(tree.Element)(this.combinator,
+ this.value.eval ? this.value.eval(env) : this.value,
+ this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+ var value = (this.value.toCSS ? this.value.toCSS(env) : this.value);
+ if (value == '' && this.combinator.value.charAt(0) == '&') {
+ return '';
+ } else {
+ return this.combinator.toCSS(env || {}) + value;
+ }
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ ':' : ' :',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS ? e.toCSS(env) : '';
+ }).join(' ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, once, index) {
+ var that = this;
+
+ this.once = once;
+ this.index = index;
+ this._path = path;
+ this.features = features && new(tree.Value)(features);
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css(\?.*)?$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (e, root, imported) {
+ if (e) { e.index = index }
+ if (imported && that.once) that.skip = imported;
+ that.root = root || new(tree.Ruleset)([], []);
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function (env) {
+ var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+ if (this.css) {
+ return "@import " + this._path.toCSS() + features + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset, features = this.features && this.features.eval(env);
+
+ if (this.skip) return [];
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value },
+ compare: function (other) {
+ if (other instanceof tree.Keyword) {
+ return other.value === this.value ? 0 : 1;
+ } else {
+ return -1;
+ }
+ }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Media = function (value, features) {
+ var selectors = this.emptySelectors();
+
+ this.features = new(tree.Value)(features);
+ this.ruleset = new(tree.Ruleset)(selectors, value);
+ this.ruleset.allowImports = true;
+};
+tree.Media.prototype = {
+ toCSS: function (ctx, env) {
+ var features = this.features.toCSS(env);
+
+ this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
+ return '@media ' + features + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ },
+ eval: function (env) {
+ if (!env.mediaBlocks) {
+ env.mediaBlocks = [];
+ env.mediaPath = [];
+ }
+
+ var blockIndex = env.mediaBlocks.length;
+ env.mediaPath.push(this);
+ env.mediaBlocks.push(this);
+
+ var media = new(tree.Media)([], []);
+ if(this.debugInfo) {
+ this.ruleset.debugInfo = this.debugInfo;
+ media.debugInfo = this.debugInfo;
+ }
+ media.features = this.features.eval(env);
+
+ env.frames.unshift(this.ruleset);
+ media.ruleset = this.ruleset.eval(env);
+ env.frames.shift();
+
+ env.mediaBlocks[blockIndex] = media;
+ env.mediaPath.pop();
+
+ return env.mediaPath.length === 0 ? media.evalTop(env) :
+ media.evalNested(env)
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) },
+ emptySelectors: function() {
+ var el = new(tree.Element)('', '&', 0);
+ return [new(tree.Selector)([el])];
+ },
+
+ evalTop: function (env) {
+ var result = this;
+
+ // Render all dependent Media blocks.
+ if (env.mediaBlocks.length > 1) {
+ var selectors = this.emptySelectors();
+ result = new(tree.Ruleset)(selectors, env.mediaBlocks);
+ result.multiMedia = true;
+ }
+
+ delete env.mediaBlocks;
+ delete env.mediaPath;
+
+ return result;
+ },
+ evalNested: function (env) {
+ var i, value,
+ path = env.mediaPath.concat([this]);
+
+ // Extract the media-query conditions separated with `,` (OR).
+ for (i = 0; i < path.length; i++) {
+ value = path[i].features instanceof tree.Value ?
+ path[i].features.value : path[i].features;
+ path[i] = Array.isArray(value) ? value : [value];
+ }
+
+ // Trace all permutations to generate the resulting media-query.
+ //
+ // (a, b and c) with nested (d, e) ->
+ // a and d
+ // a and e
+ // b and c and d
+ // b and c and e
+ this.features = new(tree.Value)(this.permute(path).map(function (path) {
+ path = path.map(function (fragment) {
+ return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment);
+ });
+
+ for(i = path.length - 1; i > 0; i--) {
+ path.splice(i, 0, new(tree.Anonymous)("and"));
+ }
+
+ return new(tree.Expression)(path);
+ }));
+
+ // Fake a tree-node that doesn't output anything.
+ return new(tree.Ruleset)([], []);
+ },
+ permute: function (arr) {
+ if (arr.length === 0) {
+ return [];
+ } else if (arr.length === 1) {
+ return arr[0];
+ } else {
+ var result = [];
+ var rest = this.permute(arr.slice(1));
+ for (var i = 0; i < rest.length; i++) {
+ for (var j = 0; j < arr[0].length; j++) {
+ result.push([arr[0][j]].concat(rest[i]));
+ }
+ }
+ return result;
+ }
+ },
+ bubbleSelectors: function (selectors) {
+ this.ruleset = new(tree.Ruleset)(selectors.slice(0), [this.ruleset]);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+ this.filename = filename;
+ this.important = important;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) {
+ return { name: a.name, value: a.value.eval(env) };
+ });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments, this.important).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { type: 'Runtime',
+ message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index, filename: this.filename };
+ }
+ }
+ }
+ throw { type: 'Name',
+ message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index, filename: this.filename };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition, variadic) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.condition = condition;
+ this.variadic = variadic;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ evalParams: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []), varargs, arg;
+
+ for (var i = 0, val, name; i < this.params.length; i++) {
+ arg = args && args[i]
+
+ if (arg && arg.name) {
+ frame.rules.unshift(new(tree.Rule)(arg.name, arg.value.eval(env)));
+ args.splice(i, 1);
+ i--;
+ continue;
+ }
+
+ if (name = this.params[i].name) {
+ if (this.params[i].variadic && args) {
+ varargs = [];
+ for (var j = i; j < args.length; j++) {
+ varargs.push(args[j].value.eval(env));
+ }
+ frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
+ } else if (val = (arg && arg.value) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(name, val.eval(env)));
+ } else {
+ throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ return frame;
+ },
+ eval: function (env, args, important) {
+ var frame = this.evalParams(env, args), context, _arguments = [], rules, start;
+
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push((args[i] && args[i].value) || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ rules = important ?
+ this.rules.map(function (r) {
+ return new(tree.Rule)(r.name, r.value, '!important', r.index);
+ }) : this.rules.slice(0);
+
+ return new(tree.Ruleset)(null, rules).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len, frame;
+
+ if (! this.variadic) {
+ if (argsLength < this.required) { return false }
+ if (argsLength > this.params.length) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+ }
+
+ if (this.condition && !this.condition.eval({
+ frames: [this.evalParams(env, args)].concat(env.frames)
+ })) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+ this.value = node;
+};
+tree.Paren.prototype = {
+ toCSS: function (env) {
+ return '(' + this.value.toCSS(env) + ')';
+ },
+ eval: function (env) {
+ return new(tree.Paren)(this.value.eval(env));
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return ('value' in v) ? v.value : v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ },
+ compare: function (x) {
+ if (!x.toCSS) {
+ return -1;
+ }
+
+ var left = this.toCSS(),
+ right = x.toCSS();
+
+ if (left === right) {
+ return 0;
+ }
+
+ return left < right ? -1 : 1;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ratio = function (value) {
+ this.value = value;
+};
+tree.Ratio.prototype = {
+ toCSS: function (env) {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+ this.inline = inline || false;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + (this.inline ? "" : ";");
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name,
+ this.value.eval(context),
+ this.important,
+ this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules, strictImports) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+ this.strictImports = strictImports;
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+ var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports);
+ var rules = [];
+
+ ruleset.root = this.root;
+ ruleset.allowImports = this.allowImports;
+
+ if(this.debugInfo) {
+ ruleset.debugInfo = this.debugInfo;
+ }
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ rules = rules.concat(ruleset.rules[i].eval(env));
+ } else {
+ rules.push(ruleset.rules[i]);
+ }
+ }
+ ruleset.rules = rules;
+ rules = [];
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0;
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ rules = rules.concat(ruleset.rules[i].eval(env));
+ } else {
+ rules.push(ruleset.rules[i]);
+ }
+ }
+ ruleset.rules = rules;
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ if (env.mediaBlocks) {
+ for(var i = mediaBlockCount; i < env.mediaBlocks.length; i++) {
+ env.mediaBlocks[i].bubbleSelectors(selectors);
+ }
+ }
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > rule.selectors[j].elements.length) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ _rules = [], //
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ debugInfo, // Line number debugging
+ rule;
+
+ if (! this.root) {
+ this.joinSelectors(paths, context, this.selectors);
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive) || (rule instanceof tree.Media)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ debugInfo = tree.debugInfo(env, this);
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : ',\n');
+
+ // Remove duplicates
+ for (var i = rules.length - 1; i >= 0; i--) {
+ if (_rules.indexOf(rules[i]) === -1) {
+ _rules.unshift(rules[i]);
+ }
+ }
+ rules = _rules;
+
+ css.push(debugInfo + selector +
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ },
+
+ joinSelectors: function (paths, context, selectors) {
+ for (var s = 0; s < selectors.length; s++) {
+ this.joinSelector(paths, context, selectors[s]);
+ }
+ },
+
+ joinSelector: function (paths, context, selector) {
+
+ var i, j, k,
+ hasParentSelector, newSelectors, el, sel, parentSel,
+ newSelectorPath, afterParentJoin, newJoinedSelector,
+ newJoinedSelectorEmpty, lastSelector, currentElements,
+ selectorsMultiplied;
+
+ for (i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ if (el.value === '&') {
+ hasParentSelector = true;
+ }
+ }
+
+ if (!hasParentSelector) {
+ if (context.length > 0) {
+ for(i = 0; i < context.length; i++) {
+ paths.push(context[i].concat(selector));
+ }
+ }
+ else {
+ paths.push([selector]);
+ }
+ return;
+ }
+
+ // The paths are [[Selector]]
+ // The first list is a list of comma seperated selectors
+ // The inner list is a list of inheritance seperated selectors
+ // e.g.
+ // .a, .b {
+ // .c {
+ // }
+ // }
+ // == [[.a] [.c]] [[.b] [.c]]
+ //
+
+ // the elements from the current selector so far
+ currentElements = [];
+ // the current list of new selectors to add to the path.
+ // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
+ // by the parents
+ newSelectors = [[]];
+
+ for (i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ // non parent reference elements just get added
+ if (el.value !== "&") {
+ currentElements.push(el);
+ } else {
+ // the new list of selectors to add
+ selectorsMultiplied = [];
+
+ // merge the current list of non parent selector elements
+ // on to the current list of selectors to add
+ if (currentElements.length > 0) {
+ this.mergeElementsOnToSelectors(currentElements, newSelectors);
+ }
+
+ // loop through our current selectors
+ for(j = 0; j < newSelectors.length; j++) {
+ sel = newSelectors[j];
+ // if we don't have any parent paths, the & might be in a mixin so that it can be used
+ // whether there are parents or not
+ if (context.length == 0) {
+ // the combinator used on el should now be applied to the next element instead so that
+ // it is not lost
+ if (sel.length > 0) {
+ sel[0].elements = sel[0].elements.slice(0);
+ sel[0].elements.push(new(tree.Element)(el.combinator, '', 0)); //new Element(el.Combinator, ""));
+ }
+ selectorsMultiplied.push(sel);
+ }
+ else {
+ // and the parent selectors
+ for(k = 0; k < context.length; k++) {
+ parentSel = context[k];
+ // We need to put the current selectors
+ // then join the last selector's elements on to the parents selectors
+
+ // our new selector path
+ newSelectorPath = [];
+ // selectors from the parent after the join
+ afterParentJoin = [];
+ newJoinedSelectorEmpty = true;
+
+ //construct the joined selector - if & is the first thing this will be empty,
+ // if not newJoinedSelector will be the last set of elements in the selector
+ if (sel.length > 0) {
+ newSelectorPath = sel.slice(0);
+ lastSelector = newSelectorPath.pop();
+ newJoinedSelector = new(tree.Selector)(lastSelector.elements.slice(0));
+ newJoinedSelectorEmpty = false;
+ }
+ else {
+ newJoinedSelector = new(tree.Selector)([]);
+ }
+
+ //put together the parent selectors after the join
+ if (parentSel.length > 1) {
+ afterParentJoin = afterParentJoin.concat(parentSel.slice(1));
+ }
+
+ if (parentSel.length > 0) {
+ newJoinedSelectorEmpty = false;
+
+ // join the elements so far with the first part of the parent
+ newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, 0));
+ newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1));
+ }
+
+ if (!newJoinedSelectorEmpty) {
+ // now add the joined selector
+ newSelectorPath.push(newJoinedSelector);
+ }
+
+ // and the rest of the parent
+ newSelectorPath = newSelectorPath.concat(afterParentJoin);
+
+ // add that to our new set of selectors
+ selectorsMultiplied.push(newSelectorPath);
+ }
+ }
+ }
+
+ // our new selectors has been multiplied, so reset the state
+ newSelectors = selectorsMultiplied;
+ currentElements = [];
+ }
+ }
+
+ // if we have any elements left over (e.g. .a& .b == .b)
+ // add them on to all the current selectors
+ if (currentElements.length > 0) {
+ this.mergeElementsOnToSelectors(currentElements, newSelectors);
+ }
+
+ for(i = 0; i < newSelectors.length; i++) {
+ paths.push(newSelectors[i]);
+ }
+ },
+
+ mergeElementsOnToSelectors: function(elements, selectors) {
+ var i, sel;
+
+ if (selectors.length == 0) {
+ selectors.push([ new(tree.Selector)(elements) ]);
+ return;
+ }
+
+ for(i = 0; i < selectors.length; i++) {
+ sel = selectors[i];
+
+ // if the previous thing in sel is a parent this needs to join on to it
+ if (sel.length > 0) {
+ sel[sel.length - 1] = new(tree.Selector)(sel[sel.length - 1].elements.concat(elements));
+ }
+ else {
+ sel.push(new(tree.Selector)(elements));
+ }
+ }
+ }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+};
+tree.Selector.prototype.match = function (other) {
+ var len = this.elements.length,
+ olen = other.elements.length,
+ max = Math.min(len, olen);
+
+ if (len < olen) {
+ return false;
+ } else {
+ for (var i = 0; i < max; i++) {
+ if (this.elements[i].value !== other.elements[i].value) {
+ return false;
+ }
+ }
+ }
+ return true;
+};
+tree.Selector.prototype.eval = function (env) {
+ return new(tree.Selector)(this.elements.map(function (e) {
+ return e.eval(env);
+ }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ if (this.elements[0].combinator.value === "") {
+ this._css = ' ';
+ } else {
+ this._css = '';
+ }
+
+ this._css += this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+
+ return this._css;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ this.value = val;
+ this.paths = paths;
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + this.value.toCSS() + ")";
+ },
+ eval: function (ctx) {
+ var val = this.value.eval(ctx);
+
+ // Add the base path if the URL is relative and we are either
+ // a.) in the browser or
+ // b.) we have a relative file URL
+ if ((this.paths.length > 0) &&
+ (typeof window !== 'undefined' || !/^(?:[A-Za-z-]+:|\/)/.test(this.paths[0])) &&
+ (typeof val.value === "string" && !/^(?:[a-z-]+:|\/)/.test(val.value))) {
+ var path = this.paths[0].slice(-1) === '/' ? this.paths[0] : this.paths[0] + '/';
+ var v = path + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ val = new(tree.Anonymous)(v);
+ }
+
+ return new(tree.URL)(val, this.paths);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { type: 'Name',
+ message: "variable " + name + " is undefined",
+ filename: this.file,
+ index: this.index };
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.debugInfo = function(env, ctx) {
+ var result="";
+ if (env.dumpLineNumbers && !env.compress) {
+ switch(env.dumpLineNumbers) {
+ case 'comments':
+ result = tree.debugInfo.asComment(ctx);
+ break;
+ case 'mediaquery':
+ result = tree.debugInfo.asMediaQuery(ctx);
+ break;
+ case 'all':
+ result = tree.debugInfo.asComment(ctx)+tree.debugInfo.asMediaQuery(ctx);
+ break;
+ }
+ }
+ return result;
+};
+
+tree.debugInfo.asComment = function(ctx) {
+ return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n';
+};
+
+tree.debugInfo.asMediaQuery = function(ctx) {
+ return '@media -sass-debug-info{filename{font-family:"' + ctx.debugInfo.fileName + '";}line{font-family:"' + ctx.debugInfo.lineNumber + '";}}\n';
+};
+
+tree.find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+tree.jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+
+})(require('./tree'));
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = less.async || false;
+less.fileAsync = less.fileAsync || false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);
+ if (dumpLineNumbers) {
+ less.dumpLineNumbers = dumpLineNumbers[1];
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (e, root, _, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (e, root, _, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)({
+ filename: document.location.href.replace(/#.*$/, ''),
+ dumpLineNumbers: less.dumpLineNumbers
+ }).parse(styles[i].innerHTML || '', function (e, tree) {
+ var css = tree.toCSS();
+ var style = styles[i];
+ style.type = 'text/css';
+ if (style.styleSheet) {
+ style.styleSheet.cssText = css;
+ } else {
+ style.innerHTML = css;
+ }
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var contents = sheet.contents || {}; // Passing a ref to top importing parser content cache trough 'sheet' arg.
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^[a-z-]+:/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, null, data, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ contents[href] = data; // Updating top importing parser content cache
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type,
+ filename: href,
+ 'contents': contents, // Passing top importing parser content cache ref down.
+ dumpLineNumbers: less.dumpLineNumbers
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ if( sheet.media ){ css.media = sheet.media; }
+ css.id = id;
+ var nextEl = sheet && sheet.nextSibling || null;
+ document.getElementsByTagName('head')[0].insertBefore(css, nextEl);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ try {
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ } catch(e) {
+ //TODO - could do with adding more robust error handling
+ log('failed to save');
+ }
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? less.fileAsync : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol && !less.fileAsync) {
+ if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+ var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+ var elem = document.createElement('div'), timer, content, error = [];
+ var filename = e.filename || href;
+ var filenameNoPath = filename.match(/([^\/]+)$/)[1];
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p>in <a href="' + filename + '">' + filenameNoPath + "</a> ";
+
+ var errorline = function (e, i, classname) {
+ if (e.extract[i]) {
+ error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
+ .replace(/\{class\}/, classname)
+ .replace(/\{content\}/, e.extract[i]));
+ }
+ };
+
+ if (e.stack) {
+ content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+ } else if (e.extract) {
+ errorline(e, 0, '');
+ errorline(e, 1, 'line');
+ errorline(e, 2, '');
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ '<ul>' + error.join('') + '</ul>';
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #dd6666;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.line {',
+ 'color: #ff0000;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
+// amd.js
+//
+// Define Less as an AMD module.
+if (typeof define === "function" && define.amd) {
+ define("less", [], function () { return less; } );
+}
+})(window);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistless130eminjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0e.min.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0e.min.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-1.3.0e.min.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+//
+// LESS - Leaner CSS v1.3.0
+// http://lesscss.org
+//
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(e,t){function n(t){return e.less[t.split("/")[1]]}function h(){var e=document.getElementsByTagName("style");for(var t=0;t<e.length;t++)e[t].type.match(l)&&(new r.Parser({filename:document.location.href.replace(/#.*$/,""),dumpLineNumbers:r.dumpLineNumbers})).parse(e[t].innerHTML||"",function(n,r){var i=r.toCSS(),s=e[t];s.type="text/css",s.styleSheet?s.styleSheet.cssText=i:s.innerHTML=i})}function p(e,t){for(var n=0;n<r.sheets.length;n++)d(r.sheets[n],e,t,r.sheets.length-(n+1))}function d(t,n,i,s){var o=t.contents||{},a=e.location.href.replace(/[#?].*$/,""),f=t.href.replace(/\?.*$/,""),l=u&&u.getItem(f),c=u&&u.getItem(f+":timestamp"),h={css:l,timestamp:c};/^[a-z-]+:/.test(f)||(f.charAt(0)=="/"?f=e.location.protocol+"//"+e.location.host+f:f=a.slice(0,a.lastIndexOf("/")+1)+f),g(t.href,t.type,function(e,u){if(!i&&h&&u&&a
mp;(new Date(u)).valueOf()===(new Date(h.timestamp)).valueOf())m(h.css,t),n(null,null,e,t,{local:!0,remaining:s});else try{o[f]=e,(new r.Parser({optimization:r.optimization,paths:[f.replace(/[\w\.-]+$/,"")],mime:t.type,filename:f,contents:o,dumpLineNumbers:r.dumpLineNumbers})).parse(e,function(r,i){if(r)return E(r,f);try{n(r,i,e,t,{local:!1,lastModified:u,remaining:s}),b(document.getElementById("less-error-message:"+v(f)))}catch(r){E(r,f)}})}catch(a){E(a,f)}},function(e,t){throw new Error("Couldn't load "+t+" ("+e+")")})}function v(e){return e.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"").replace(/\?.*$/,"").replace(/\.[^\.\/]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function m(e,t,n){var r,i=t.href?t.href.replace(/\?.*$/,""):"",s="less:"+(t.title||v(i));if((r=document.getElementById(s))===null){r=document.createElement("st
yle"),r.type="text/css",t.media&&(r.media=t.media),r.id=s;var o=t&&t.nextSibling||null;document.getElementsByTagName("head")[0].insertBefore(r,o)}if(r.styleSheet)try{r.styleSheet.cssText=e}catch(a){throw new Error("Couldn't reassign styleSheet.cssText.")}else(function(e){r.childNodes.length>0?r.firstChild.nodeValue!==e.nodeValue&&r.replaceChild(e,r.firstChild):r.appendChild(e)})(document.createTextNode(e));if(n&&u){w("saving "+i+" to cache.");try{u.setItem(i,e),u.setItem(i+":timestamp",n)}catch(a){w("failed to save")}}}function g(e,t,n,i){function a(t,n,r){t.status>=200&&t.status<300?n(t.responseText,t.getResponseHeader("Last-Modified")):typeof r=="function"&&r(t.status,e)}var o=y(),u=s?r.fileAsync:r.async;typeof o.overrideMimeType=="function"&&o.overrideMimeType("text/css"),o.open("GET",e,u),o.s
etRequestHeader("Accept",t||"text/x-less, text/css; q=0.9, */*; q=0.5"),o.send(null),s&&!r.fileAsync?o.status===0||o.status>=200&&o.status<300?n(o.responseText):i(o.status,e):u?o.onreadystatechange=function(){o.readyState==4&&a(o,n,i)}:a(o,n,i)}function y(){if(e.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(t){return w("browser doesn't support AJAX."),null}}function b(e){return e&&e.parentNode.removeChild(e)}function w(e){r.env=="development"&&typeof console!="undefined"&&console.log("less: "+e)}function E(e,t){var n="less-error-message:"+v(t),i='<li><label>{line}</label><pre class="{class}">{content}</pre></li>',s=document.createElement("div"),o,u,a=[],f=e.filename||t,l=f.match(/([^\/]+)$/)[1];s.id=n,s.className="less-error-message",u
="<h3>"+(e.message||"There is an error in your .less file")+"</h3>"+'<p>in <a href="'+f+'">'+l+"</a> ";var c=function(e,t,n){e.extract[t]&&a.push(i.replace(/\{line\}/,parseInt(e.line)+(t-1)).replace(/\{class\}/,n).replace(/\{content\}/,e.extract[t]))};e.stack?u+="<br/>"+e.stack.split("\n").slice(1).join("<br/>"):e.extract&&(c(e,0,""),c(e,1,"line"),c(e,2,""),u+="on line "+e.line+", column "+(e.column+1)+":</p>"+"<ul>"+a.join("")+"</ul>"),s.innerHTML=u,m([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;"
,"padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),s.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius:
5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),r.env=="development"&&(o=setInterval(function(){document.body&&(document.getElementById(n)?document.body.replaceChild(s,document.getElementById(n)):document.body.insertBefore(s,document.body.firstChild),clearInterval(o))},10))}Array.isArray||(Array.isArray=function(e){return Object.prototype.toString.call(e)==="[object Array]"||e instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(e,t){var n=this.length>>>0;for(var r=0;r<n;r++)r in this&&e.call(t,this[r],r,this)}),Array.prototype.map||(Array.prototype.map=function(e){var t=this.length>>>0,n=new Array(t),r=arguments[1];for(var i=0;i<t;i++)i in this&&(n[i]=e.call(r,this[i],i,this));return n}),Array.prototype.filter||(Array.prototype.filter=function(e){var t=[],n=arguments[1];for(var r=0;
r<this.length;r++)e.call(n,this[r])&&t.push(this[r]);return t}),Array.prototype.reduce||(Array.prototype.reduce=function(e){var t=this.length>>>0,n=0;if(t===0&&arguments.length===1)throw new TypeError;if(arguments.length>=2)var r=arguments[1];else do{if(n in this){r=this[n++];break}if(++n>=t)throw new TypeError}while(!0);for(;n<t;n++)n in this&&(r=e.call(null,r,this[n],n,this));return r}),Array.prototype.indexOf||(Array.prototype.indexOf=function(e){var t=this.length,n=arguments[1]||0;if(!t)return-1;if(n>=t)return-1;n<0&&(n+=t);for(;n<t;n++){if(!Object.prototype.hasOwnProperty.call(this,n))continue;if(e===this[n])return n}return-1}),Object.keys||(Object.keys=function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.push(n);return t}),String.prototype.trim||(String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")});var r,i;typeof envi
ronment=="object"&&{}.toString.call(environment)==="[object Environment]"?(typeof e=="undefined"?r={}:r=e.less={},i=r.tree={},r.mode="rhino"):typeof e=="undefined"?(r=exports,i=n("./tree"),r.mode="node"):(typeof e.less=="undefined"&&(e.less={}),r=e.less,i=e.less.tree={},r.mode="browser"),r.Parser=function(t){function g(){a=c[u],f=o,h=o}function y(){c[u]=a,o=f,h=o}function b(){o>h&&(c[u]=c[u].slice(o-h),h=o)}function w(e){var t=e.charCodeAt(0);return t===32||t===10||t===9}function E(e){var t,n,r,i,a;if(e instanceof Function)return e.call(p.parsers);if(typeof e=="string")t=s.charAt(o)===e?e:null,r=1,b();else{b();if(!(t=e.exec(c[u])))return null;r=t[0].length}if(t)return S(r),typeof t=="string"?t:t.length===1?t[0]:t}function S(e){var t=o,n=u,r=o+c[u].length,i=o+=e;while(o<r){if(!w(s.charAt(o)))break;o++}return c[u]=c[u].slice(e+(o-i)),h=o,c[u].leng
th===0&&u<c.length-1&&u++,t!==o||n!==u}function x(e,t){var n=E(e);if(!!n)return n;T(t||(typeof e=="string"?"expected '"+e+"' got '"+s.charAt(o)+"'":"unexpected token"))}function T(e,t){throw{index:o,type:t||"Syntax",message:e}}function N(e){return typeof e=="string"?s.charAt(o)===e:e.test(c[u])?!0:!1}function C(e,t){return e.filename&&t.filename&&e.filename!==t.filename?p.imports.contents[e.filename]:s}function k(e,t){for(var n=e,r=-1;n>=0&&t.charAt(n)!=="\n";n--)r++;return{line:typeof e=="number"?(t.slice(0,e).match(/\n/g)||"").length:null,column:r}}function L(e){return r.mode==="browser"||r.mode==="rhino"?e.filename:n("path").resolve(e.filename)}function A(e,t,n){return{lineNumber:k(e,t).line+1,fileName:L(n)}}function O(e,t){var n=C(e,t),r=k(e.index,n),i=r.line,s=r.column,o=n.split("\n");this.type=
e.type||"Syntax",this.message=e.message,this.filename=e.filename||t.filename,this.index=e.index,this.line=typeof i=="number"?i+1:null,this.callLine=e.call&&k(e.call,n).line+1,this.callExtract=o[k(e.call,n).line],this.stack=e.stack,this.column=s,this.extract=[o[i-1],o[i],o[i+1]]}var s,o,u,a,f,l,c,h,p,d=this,t=t||{};t.contents||(t.contents={});var v=function(){},m=this.imports={paths:t&&t.paths||[],queue:[],files:{},contents:t.contents,mime:t&&t.mime,error:null,push:function(e,n){var i=this;this.queue.push(e),r.Parser.importer(e,this.paths,function(t,r){i.queue.splice(i.queue.indexOf(e),1);var s=e in i.files;i.files[e]=r,t&&!i.error&&(i.error=t),n(t,r,s),i.queue.length===0&&v(t)},t)}};return this.env=t=t||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.filename=this.env.filename||null,p={imports:m,parse:function(e,a){var f,d,m,g,y,b,w=[],S,x=null;o=u=h=l=0,s=e.replace(/\r\n/g,
"\n"),s=s.replace(/^\uFEFF/,""),c=function(e){var n=0,r=/(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,i=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,o=/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,u=0,a,f=e[0],l;for(var c=0,h,p;c<s.length;c++){r.lastIndex=c,(a=r.exec(s))&&a.index===c&&(c+=a[0].length,f.push(a[0])),h=s.charAt(c),i.lastIndex=o.lastIndex=c,(a=o.exec(s))&&a.index===c&&(c+=a[0].length,f.push(a[0]),h=s.charAt(c)),!l&&h==="/"&&(p=s.charAt(c+1),(p==="/"||p==="*")&&(a=i.exec(s))&&a.index===c&&(c+=a[0].length,f.push(a[0]),h=s.charAt(c)));switch(h){case"{":if(!l){u++,f.push(h);break};case"}":if(!l){u--,f.push(h),e[++n]=f=[];break};case"(":if(!l){l=!0,f.push(h);break};case")":if(l){l=!1,f.push(h);break};default:f.push(h)}}return u>0&&(x=new O({index:c,type:"Parse",m
essage:"missing closing `}`",filename:t.filename},t)),e.map(function(e){return e.join("")})}([[]]);if(x)return a(x);try{f=new i.Ruleset([],E(this.parsers.primary)),f.root=!0}catch(T){return a(new O(T,t))}f.toCSS=function(e){var s,o,u;return function(s,o){var u=[],a;s=s||{},typeof o=="object"&&!Array.isArray(o)&&(o=Object.keys(o).map(function(e){var t=o[e];return t instanceof i.Value||(t instanceof i.Expression||(t=new i.Expression([t])),t=new i.Value([t])),new i.Rule("@"+e,t,!1,0)}),u=[new i.Ruleset(null,o)]);try{var f=e.call(this,{frames:u}).toCSS([],{compress:s.compress||!1,dumpLineNumbers:t.dumpLineNumbers})}catch(l){throw new O(l,t)}if(a=p.imports.error)throw a instanceof O?a:new O(a,t);return s.yuicompress&&r.mode==="node"?n("./cssmin").compressor.cssmin(f):s.compress?f.replace(/(\s)+/g,"$1"):f}}(f.eval);if(o<s.length-1){o=l,b=s.split("\n"),y=(s.slice(0,o).match(/\n/g)||&q
uot;").length+1;for(var N=o,C=-1;N>=0&&s.charAt(N)!=="\n";N--)C++;x={type:"Parse",message:"Syntax Error on line "+y,index:o,filename:t.filename,line:y,column:C,extract:[b[y-2],b[y-1],b[y]]}}this.imports.queue.length>0?v=function(e){e?a(e):a(null,f)}:a(x,f)},parsers:{primary:function(){var e,t=[];while((e=E(this.mixin.definition)||E(this.rule)||E(this.ruleset)||E(this.mixin.call)||E(this.comment)||E(this.directive))||E(/^[\s\n]+/))e&&t.push(e);return t},comment:function(){var e;if(s.charAt(o)!=="/")return;if(s.charAt(o+1)==="/")return new i.Comment(E(/^\/\/.*/),!0);if(e=E(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new i.Comment(e)},entities:{quoted:function(){var e,t=o,n;s.charAt(t)==="~"&&(t++,n=!0);if(s.charAt(t)!=='"'&&s.charAt(t)!=="'")return;n&&E("~");if(e=E(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new i.Quoted(e
[0],e[1]||e[2],n)},keyword:function(){var e;if(e=E(/^[_A-Za-z-][_A-Za-z0-9-]*/))return i.colors.hasOwnProperty(e)?new i.Color(i.colors[e].slice(1)):new i.Keyword(e)},call:function(){var e,n,r,s,a=o;if(!(e=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(c[u])))return;e=e[1],n=e.toLowerCase();if(n==="url")return null;o+=e.length;if(n==="alpha"){s=E(this.alpha);if(typeof s!="undefined")return s}E("("),r=E(this.entities.arguments);if(!E(")"))return;if(e)return new i.Call(e,r,a,t.filename)},arguments:function(){var e=[],t;while(t=E(this.entities.assignment)||E(this.expression)){e.push(t);if(!E(","))break}return e},literal:function(){return E(this.entities.ratio)||E(this.entities.dimension)||E(this.entities.color)||E(this.entities.quoted)},assignment:function(){var e,t;if((e=E(/^\w+(?=\s?=)/i))&&E("=")&&(t=E(this.entity)))return new i.Assignment(e,t)},url:function(){var e;if(s.charAt(o)!=="u"||!E(/^url\(/)
)return;return e=E(this.entities.quoted)||E(this.entities.variable)||E(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/)||"",x(")"),new i.URL(e.value!=null||e instanceof i.Variable?e:new i.Anonymous(e),m.paths)},variable:function(){var e,n=o;if(s.charAt(o)==="@"&&(e=E(/^@@?[\w-]+/)))return new i.Variable(e,n,t.filename)},variableCurly:function(){var e,n,r=o;if(s.charAt(o)==="@"&&(n=E(/^@\{([\w-]+)\}/)))return new i.Variable("@"+n[1],r,t.filename)},color:function(){var e;if(s.charAt(o)==="#"&&(e=E(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/)))return new i.Color(e[1])},dimension:function(){var e,t=s.charCodeAt(o);if(t>57||t<45||t===47)return;if(e=E(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn|dpi|dpcm|dppx|rem|vw|vh|vmin|vm|ch)?/))return new i.Dimension(e[1],e[2])},ratio:function(){var e,t=s.charCodeAt(o);if(t>57||t<48)return;if(e=E(/^(\d+\/\d+)/))return new i.Ratio(e[1])},javascript:
function(){var e,t=o,n;s.charAt(t)==="~"&&(t++,n=!0);if(s.charAt(t)!=="`")return;n&&E("~");if(e=E(/^`([^`]*)`/))return new i.JavaScript(e[1],o,n)}},variable:function(){var e;if(s.charAt(o)==="@"&&(e=E(/^(@[\w-]+)\s*:/)))return e[1]},shorthand:function(){var e,t;if(!N(/^[@\w.%-]+\/[@\w.-]+/))return;g();if((e=E(this.entity))&&E("/")&&(t=E(this.entity)))return new i.Shorthand(e,t);y()},mixin:{call:function(){var e=[],n,r,u=[],a,f=o,l=s.charAt(o),c,h,p=!1;if(l!=="."&&l!=="#")return;g();while(n=E(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/))e.push(new i.Element(r,n,o)),r=E(">");if(E("(")){while(a=E(this.expression)){h=a,c=null;if(a.value.length==1){var d=a.value[0];if(d instanceof i.Variable&&E(":")){if(!(h=E(this.expression)))throw new Error("Expected value");c=d.name}}u.push({name:c,value:h});if(!E(",&q
uot;))break}if(!E(")"))throw new Error("Expected )")}E(this.important)&&(p=!0);if(e.length>0&&(E(";")||N("}")))return new i.mixin.Call(e,u,f,t.filename,p);y()},definition:function(){var e,t=[],n,r,u,a,f,c=!1;if(s.charAt(o)!=="."&&s.charAt(o)!=="#"||N(/^[^{]*(;|})/))return;g();if(n=E(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)){e=n[1];do{if(s.charAt(o)==="."&&E(/^\.{3}/)){c=!0;break}if(!(u=E(this.entities.variable)||E(this.entities.literal)||E(this.entities.keyword)))break;if(u instanceof i.Variable)if(E(":"))a=x(this.expression,"expected expression"),t.push({name:u.name,value:a});else{if(E(/^\.{3}/)){t.push({name:u.name,variadic:!0}),c=!0;break}t.push({name:u.name})}else t.push({value:u})}while(E(","));E(")")||(l=o,y()),E(/^when/)&&(f=x(this.conditions,"expected condition")),r=E(this.block);if(r)return
new i.mixin.Definition(e,t,r,f,c);y()}}},entity:function(){return E(this.entities.literal)||E(this.entities.variable)||E(this.entities.url)||E(this.entities.call)||E(this.entities.keyword)||E(this.entities.javascript)||E(this.comment)},end:function(){return E(";")||N("}")},alpha:function(){var e;if(!E(/^\(opacity=/i))return;if(e=E(/^\d+/)||E(this.entities.variable))return x(")"),new i.Alpha(e)},element:function(){var e,t,n,r;n=E(this.combinator),e=E(/^(?:\d+\.\d+|\d+)%/)||E(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)||E("*")||E("&")||E(this.attribute)||E(/^\([^)@]+\)/)||E(/^[\.#](?=@)/)||E(this.entities.variableCurly),e||E("(")&&(r=E(this.entities.variableCurly)||E(this.entities.variable))&&E(")")&&(e=new i.Paren(r));if(e)return new i.Element(n,e,o)},combinator:function(){var e,t=s.charAt(o);if(t===">"||t==="+"||t==="~")
{o++;while(s.charAt(o).match(/\s/))o++;return new i.Combinator(t)}return s.charAt(o-1).match(/\s/)?new i.Combinator(" "):new i.Combinator(null)},selector:function(){var e,t,n=[],r,u;if(E("("))return e=E(this.entity),x(")"),new i.Selector([new i.Element("",e,o)]);while(t=E(this.element)){r=s.charAt(o),n.push(t);if(r==="{"||r==="}"||r===";"||r===",")break}if(n.length>0)return new i.Selector(n)},tag:function(){return E(/^[A-Za-z][A-Za-z-]*[0-9]?/)||E("*")},attribute:function(){var e="",t,n,r;if(!E("["))return;if(t=E(/^(?:[_A-Za-z0-9-]|\\.)+/)||E(this.entities.quoted))(r=E(/^[|~*$^]?=/))&&(n=E(this.entities.quoted)||E(/^[\w-]+/))?e=[t,r,n.toCSS?n.toCSS():n].join(""):e=t;if(!E("]"))return;if(e)return"["+e+"]"},block:function(){var e;if(E("{")&&(e=E(this.primary))&&E("}"))return e},ruleset:funct
ion(){var e=[],n,r,u,a;g(),t.dumpLineNumbers&&(a=A(o,s,t));while(n=E(this.selector)){e.push(n),E(this.comment);if(!E(","))break;E(this.comment)}if(e.length>0&&(r=E(this.block))){var f=new i.Ruleset(e,r,t.strictImports);return t.dumpLineNumbers&&(f.debugInfo=a),f}l=o,y()},rule:function(){var e,t,n=s.charAt(o),r,a;g();if(n==="."||n==="#"||n==="&")return;if(e=E(this.variable)||E(this.property)){e.charAt(0)!="@"&&(a=/^([^@+\/'"*`(;{}-]*);/.exec(c[u]))?(o+=a[0].length-1,t=new i.Anonymous(a[1])):e==="font"?t=E(this.font):t=E(this.value),r=E(this.important);if(t&&E(this.end))return new i.Rule(e,t,r,f);l=o,y()}},"import":function(){var e,t,n=o;g();var r=E(/^@import(?:-(once))?\s+/);if(r&&(e=E(this.entities.quoted)||E(this.entities.url))){t=E(this.mediaFeatures);if(E(";"))return new i.Import(e,m,t,r[1]==="once",n)}y()},mediaFeature:function(){v
ar e,t,n=[];do if(e=E(this.entities.keyword))n.push(e);else if(E("(")){t=E(this.property),e=E(this.entity);if(!E(")"))return null;if(t&&e)n.push(new i.Paren(new i.Rule(t,e,null,o,!0)));else{if(!e)return null;n.push(new i.Paren(e))}}while(e);if(n.length>0)return new i.Expression(n)},mediaFeatures:function(){var e,t=[];do if(e=E(this.mediaFeature)){t.push(e);if(!E(","))break}else if(e=E(this.entities.variable)){t.push(e);if(!E(","))break}while(e);return t.length>0?t:null},media:function(){var e,n,r,u;t.dumpLineNumbers&&(u=A(o,s,t));if(E(/^@media/)){e=E(this.mediaFeatures);if(n=E(this.block))return r=new i.Media(n,e),t.dumpLineNumbers&&(r.debugInfo=u),r}},directive:function(){var e,t,n,r,u,a,f,l,c;if(s.charAt(o)!=="@")return;if(t=E(this["import"])||E(this.media))return t;g(),e=E(/^@[a-z-]+/),f=e,e.charAt(1)=="-"&&e.indexOf("-",2)>0&&(f="@"+e.slice(e
.indexOf("-",2)+1));switch(f){case"@font-face":l=!0;break;case"@viewport":case"@top-left":case"@top-left-corner":case"@top-center":case"@top-right":case"@top-right-corner":case"@bottom-left":case"@bottom-left-corner":case"@bottom-center":case"@bottom-right":case"@bottom-right-corner":case"@left-top":case"@left-middle":case"@left-bottom":case"@right-top":case"@right-middle":case"@right-bottom":l=!0;break;case"@page":case"@document":case"@supports":case"@keyframes":l=!0,c=!0}c&&(e+=" "+(E(/^[^{]+/)||"").trim());if(l){if(n=E(this.block))return new i.Directive(e,n)}else if((t=E(this.entity))&&E(";"))return new i.Directive(e,t);y()},font:function(){var e=[],t=[],n,r,s,o;while(o=E(this.shorthand)||E(this.entity))t.pus
h(o);e.push(new i.Expression(t));if(E(","))while(o=E(this.expression)){e.push(o);if(!E(","))break}return new i.Value(e)},value:function(){var e,t=[],n;while(e=E(this.expression)){t.push(e);if(!E(","))break}if(t.length>0)return new i.Value(t)},important:function(){if(s.charAt(o)==="!")return E(/^! *important/)},sub:function(){var e;if(E("(")&&(e=E(this.expression))&&E(")"))return e},multiplication:function(){var e,t,n,r;if(e=E(this.operand)){while(!N(/^\/\*/)&&(n=E("/")||E("*"))&&(t=E(this.operand)))r=new i.Operation(n,[r||e,t]);return r||e}},addition:function(){var e,t,n,r;if(e=E(this.multiplication)){while((n=E(/^[-+]\s+/)||!w(s.charAt(o-1))&&(E("+")||E("-")))&&(t=E(this.multiplication)))r=new i.Operation(n,[r||e,t]);return r||e}},conditions:function(){var e,t,n=o,r;if(e=E(this.condition)){while(E(",")&&(t=E(this.co
ndition)))r=new i.Condition("or",r||e,t,n);return r||e}},condition:function(){var e,t,n,r,s=o,u=!1;E(/^not/)&&(u=!0),x("(");if(e=E(this.addition)||E(this.entities.keyword)||E(this.entities.quoted))return(r=E(/^(?:>=|=<|[<=>])/))?(t=E(this.addition)||E(this.entities.keyword)||E(this.entities.quoted))?n=new i.Condition(r,e,t,s,u):T("expected expression"):n=new i.Condition("=",e,new i.Keyword("true"),s,u),x(")"),E(/^and/)?new i.Condition("and",n,E(this.condition)):n},operand:function(){var e,t=s.charAt(o+1);s.charAt(o)==="-"&&(t==="@"||t==="(")&&(e=E("-"));var n=E(this.sub)||E(this.entities.dimension)||E(this.entities.color)||E(this.entities.variable)||E(this.entities.call);return e?new i.Operation("*",[new i.Dimension(-1),n]):n},expression:function(){var e,t,n=[],r;while(e=E(this.addition)||E(this.entity))n.push(e);if(n.length>0
)return new i.Expression(n)},property:function(){var e;if(e=E(/^(\*?-?[_a-z0-9-]+)\s*:/))return e[1]}}}};if(r.mode==="browser"||r.mode==="rhino")r.Parser.importer=function(e,t,n,r){!/^([a-z-]+:)?\//.test(e)&&t.length>0&&(e=t[0]+e),d({href:e,title:e,type:r.mime,contents:r.contents},function(i){i&&typeof r.errback=="function"?r.errback.call(null,e,t,n,r):n.apply(null,arguments)},!0)};(function(e){function t(t){return e.functions.hsla(t.h,t.s,t.l,t.a)}function n(t){if(t instanceof e.Dimension)return parseFloat(t.unit=="%"?t.value/100:t.value);if(typeof t=="number")return t;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function r(e){return Math.min(1,Math.max(0,e))}e.functions={rgb:function(e,t,n){return this.rgba(e,t,n,1)},rgba:function(t,r,i,s){var o=[t,r,i].map(function(e){return n(e)}),s=n(s);return new e.Color(o,s)},hsl:function(e,t,n){return this.hsla
(e,t,n,1)},hsla:function(e,t,r,i){function u(e){return e=e<0?e+1:e>1?e-1:e,e*6<1?o+(s-o)*e*6:e*2<1?s:e*3<2?o+(s-o)*(2/3-e)*6:o}e=n(e)%360/360,t=n(t),r=n(r),i=n(i);var s=r<=.5?r*(t+1):r+t-r*t,o=r*2-s;return this.rgba(u(e+1/3)*255,u(e)*255,u(e-1/3)*255,i)},hue:function(t){return new e.Dimension(Math.round(t.toHSL().h))},saturation:function(t){return new e.Dimension(Math.round(t.toHSL().s*100),"%")},lightness:function(t){return new e.Dimension(Math.round(t.toHSL().l*100),"%")},red:function(t){return new e.Dimension(t.rgb[0])},green:function(t){return new e.Dimension(t.rgb[1])},blue:function(t){return new e.Dimension(t.rgb[2])},alpha:function(t){return new e.Dimension(t.toHSL().a)},luma:function(t){return new e.Dimension(Math.round((.2126*(t.rgb[0]/255)+.7152*(t.rgb[1]/255)+.0722*(t.rgb[2]/255))*t.alpha*100),"%")},saturate:function(e,n){var i=e.toHSL();return i.s+=n.value/100,i.s=r(i.s),t(i)},desaturate:function(e,n){var i=e.toHSL();return
i.s-=n.value/100,i.s=r(i.s),t(i)},lighten:function(e,n){var i=e.toHSL();return i.l+=n.value/100,i.l=r(i.l),t(i)},darken:function(e,n){var i=e.toHSL();return i.l-=n.value/100,i.l=r(i.l),t(i)},fadein:function(e,n){var i=e.toHSL();return i.a+=n.value/100,i.a=r(i.a),t(i)},fadeout:function(e,n){var i=e.toHSL();return i.a-=n.value/100,i.a=r(i.a),t(i)},fade:function(e,n){var i=e.toHSL();return i.a=n.value/100,i.a=r(i.a),t(i)},spin:function(e,n){var r=e.toHSL(),i=(r.h+n.value)%360;return r.h=i<0?360+i:i,t(r)},mix:function(t,n,r){r||(r=new e.Dimension(50));var i=r.value/100,s=i*2-1,o=t.toHSL().a-n.toHSL().a,u=((s*o==-1?s:(s+o)/(1+s*o))+1)/2,a=1-u,f=[t.rgb[0]*u+n.rgb[0]*a,t.rgb[1]*u+n.rgb[1]*a,t.rgb[2]*u+n.rgb[2]*a],l=t.alpha*i+n.alpha*(1-i);return new e.Color(f,l)},greyscale:function(t){return this.desaturate(t,new e.Dimension(100))},contrast:function(e,t,n,r){return typeof n=="undefined"&&(n=this.rgba(255,255,255,1)),typeof t=="undefined"&&(t=this.rgb
a(0,0,0,1)),typeof r=="undefined"?r=.43:r=r.value,(.2126*(e.rgb[0]/255)+.7152*(e.rgb[1]/255)+.0722*(e.rgb[2]/255))*e.alpha<r?n:t},e:function(t){return new e.Anonymous(t instanceof e.JavaScript?t.evaluated:t)},escape:function(t){return new e.Anonymous(encodeURI(t.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(t){var n=Array.prototype.slice.call(arguments,1),r=t.value;for(var i=0;i<n.length;i++)r=r.replace(/%[sda]/i,function(e){var t=e.match(/s/i)?n[i].value:n[i].toCSS();return e.match(/[A-Z]$/)?encodeURIComponent(t):t});return r=r.replace(/%%/g,"%"),new e.Quoted('"'+r+'"',r)},round:function(t,r){var i=typeof r=="undefined"?0:r.value;if(t instanceof e.Dimension)return new e.Dimension(n(t).toFixed(i),t.unit);if(typeof t=="number")return t.toFixed(i);throw{type:"
Argument",message:"argument must be a number"}},ceil:function(e){return this._math("ceil",e)},floor:function(e){return this._math("floor",e)},_math:function(t,r){if(r instanceof e.Dimension)return new e.Dimension(Math[t](n(r)),r.unit);if(typeof r=="number")return Math[t](r);throw{type:"Argument",message:"argument must be a number"}},argb:function(t){return new e.Anonymous(t.toARGB())},percentage:function(t){return new e.Dimension(t.value*100,"%")},color:function(t){if(t instanceof e.Quoted)return new e.Color(t.value.slice(1));throw{type:"Argument",message:"argument must be a string"}},iscolor:function(t){return this._isa(t,e.Color)},isnumber:function(t){return this._isa(t,e.Dimension)},isstring:function(t){return this._isa(t,e.Quoted)},iskeyword:function(t){return this._isa(t,e.Keyword)},isurl:function(t){return this._isa(t,e.URL)},ispixel:function(t){return t instanceof e.Dimension&&a
mp;t.unit==="px"?e.True:e.False},ispercentage:function(t){return t instanceof e.Dimension&&t.unit==="%"?e.True:e.False},isem:function(t){return t instanceof e.Dimension&&t.unit==="em"?e.True:e.False},_isa:function(t,n){return t instanceof n?e.True:e.False},multiply:function(e,t){var n=e.rgb[0]*t.rgb[0]/255,r=e.rgb[1]*t.rgb[1]/255,i=e.rgb[2]*t.rgb[2]/255;return this.rgb(n,r,i)},screen:function(e,t){var n=255-(255-e.rgb[0])*(255-t.rgb[0])/255,r=255-(255-e.rgb[1])*(255-t.rgb[1])/255,i=255-(255-e.rgb[2])*(255-t.rgb[2])/255;return this.rgb(n,r,i)},overlay:function(e,t){var n=e.rgb[0]<128?2*e.rgb[0]*t.rgb[0]/255:255-2*(255-e.rgb[0])*(255-t.rgb[0])/255,r=e.rgb[1]<128?2*e.rgb[1]*t.rgb[1]/255:255-2*(255-e.rgb[1])*(255-t.rgb[1])/255,i=e.rgb[2]<128?2*e.rgb[2]*t.rgb[2]/255:255-2*(255-e.rgb[2])*(255-t.rgb[2])/255;return this.rgb(n,r,i)},softlight:function(e,t){var n=t.rgb[0]*e.rgb[0]/255,r=n+e.rgb[0]*(255-(255-e.rgb[0])*(255-t.rgb[0])/255-n)
/255;n=t.rgb[1]*e.rgb[1]/255;var i=n+e.rgb[1]*(255-(255-e.rgb[1])*(255-t.rgb[1])/255-n)/255;n=t.rgb[2]*e.rgb[2]/255;var s=n+e.rgb[2]*(255-(255-e.rgb[2])*(255-t.rgb[2])/255-n)/255;return this.rgb(r,i,s)},hardlight:function(e,t){var n=t.rgb[0]<128?2*t.rgb[0]*e.rgb[0]/255:255-2*(255-t.rgb[0])*(255-e.rgb[0])/255,r=t.rgb[1]<128?2*t.rgb[1]*e.rgb[1]/255:255-2*(255-t.rgb[1])*(255-e.rgb[1])/255,i=t.rgb[2]<128?2*t.rgb[2]*e.rgb[2]/255:255-2*(255-t.rgb[2])*(255-e.rgb[2])/255;return this.rgb(n,r,i)},difference:function(e,t){var n=Math.abs(e.rgb[0]-t.rgb[0]),r=Math.abs(e.rgb[1]-t.rgb[1]),i=Math.abs(e.rgb[2]-t.rgb[2]);return this.rgb(n,r,i)},exclusion:function(e,t){var n=e.rgb[0]+t.rgb[0]*(255-e.rgb[0]-e.rgb[0])/255,r=e.rgb[1]+t.rgb[1]*(255-e.rgb[1]-e.rgb[1])/255,i=e.rgb[2]+t.rgb[2]*(255-e.rgb[2]-e.rgb[2])/255;return this.rgb(n,r,i)},average:function(e,t){var n=(e.rgb[0]+t.rgb[0])/2,r=(e.rgb[1]+t.rgb[1])/2,i=(e.rgb[2]+t.rgb[2])/2;return this.rgb(n,r,i)},negation:function(e,t){var n=255-Ma
th.abs(255-t.rgb[0]-e.rgb[0]),r=255-Math.abs(255-t.rgb[1]-e.rgb[1]),i=255-Math.abs(255-t.rgb[2]-e.rgb[2]);return this.rgb(n,r,i)},tint:function(e,t){return this.mix(this.rgb(255,255,255),e,t)},shade:function(e,t){return this.mix(this.rgb(0,0,0),e,t)}}})(n("./tree")),function(e){e.colors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",d
arkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f"
;,honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorch
id:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",sad
dlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"}}(n("./tree")),function(e){e.Alpha=function(e){this.value=e},e.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(e){return this.value.eval&&(this.value=this.value.eval(e)),this}
}}(n("../tree")),function(e){e.Anonymous=function(e){this.value=e.value||e},e.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this},compare:function(e){if(!e.toCSS)return-1;var t=this.toCSS(),n=e.toCSS();return t===n?0:t<n?-1:1}}}(n("../tree")),function(e){e.Assignment=function(e,t){this.key=e,this.value=t},e.Assignment.prototype={toCSS:function(){return this.key+"="+(this.value.toCSS?this.value.toCSS():this.value)},eval:function(t){return this.value.eval?new e.Assignment(this.key,this.value.eval(t)):this}}}(n("../tree")),function(e){e.Call=function(e,t,n,r){this.name=e,this.args=t,this.index=n,this.filename=r},e.Call.prototype={eval:function(t){var n=this.args.map(function(e){return e.eval(t)});if(!(this.name in e.functions))return new e.Anonymous(this.name+"("+n.map(function(e){return e.toCSS(t)}).join(", ")+")");try{return e.functions[this.name].apply(e.functions,n)}catch(r){t
hrow{type:r.type||"Runtime",message:"error evaluating function `"+this.name+"`"+(r.message?": "+r.message:""),index:this.index,filename:this.filename}}},toCSS:function(e){return this.eval(e).toCSS()}}}(n("../tree")),function(e){e.Color=function(e,t){Array.isArray(e)?this.rgb=e:e.length==6?this.rgb=e.match(/.{2}/g).map(function(e){return parseInt(e,16)}):this.rgb=e.split("").map(function(e){return parseInt(e+e,16)}),this.alpha=typeof t=="number"?t:1},e.Color.prototype={eval:function(){return this},toCSS:function(){return this.alpha<1?"rgba("+this.rgb.map(function(e){return Math.round(e)}).concat(this.alpha).join(", ")+")":"#"+this.rgb.map(function(e){return e=Math.round(e),e=(e>255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("")},operate:function(t,n){var r=[];n instanceof e.Color||(n=n.toColor());for(var i=0;i<3;i++)r[i]=e.
operate(t,this.rgb[i],n.rgb[i]);return new e.Color(r,this.alpha+n.alpha)},toHSL:function(){var e=this.rgb[0]/255,t=this.rgb[1]/255,n=this.rgb[2]/255,r=this.alpha,i=Math.max(e,t,n),s=Math.min(e,t,
+n),o,u,a=(i+s)/2,f=i-s;if(i===s)o=u=0;else{u=a>.5?f/(2-i-s):f/(i+s);switch(i){case e:o=(t-n)/f+(t<n?6:0);break;case t:o=(n-e)/f+2;break;case n:o=(e-t)/f+4}o/=6}return{h:o*360,s:u,l:a,a:r}},toARGB:function(){var e=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+e.map(function(e){return e=Math.round(e),e=(e>255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("")},compare:function(e){return e.rgb?e.rgb[0]===this.rgb[0]&&e.rgb[1]===this.rgb[1]&&e.rgb[2]===this.rgb[2]&&e.alpha===this.alpha?0:-1:-1}}}(n("../tree")),function(e){e.Comment=function(e,t){this.value=e,this.silent=!!t},e.Comment.prototype={toCSS:function(e){return e.compress?"":this.value},eval:function(){return this}}}(n("../tree")),function(e){e.Condition=function(e,t,n,r,i){this.op=e.trim(),this.lvalue=t,this.rvalue=n,this.index=r,this.negate=i},e.Condition.prototype.eval=function(e){var t=this.lvalue.eval(e),n=this.
rvalue.eval(e),r=this.index,i,i=function(e){switch(e){case"and":return t&&n;case"or":return t||n;default:if(t.compare)i=t.compare(n);else{if(!n.compare)throw{type:"Type",message:"Unable to perform comparison",index:r};i=n.compare(t)}switch(i){case-1:return e==="<"||e==="=<";case 0:return e==="="||e===">="||e==="=<";case 1:return e===">"||e===">="}}}(this.op);return this.negate?!i:i}}(n("../tree")),function(e){e.Dimension=function(e,t){this.value=parseFloat(e),this.unit=t||null},e.Dimension.prototype={eval:function(){return this},toColor:function(){return new e.Color([this.value,this.value,this.value])},toCSS:function(){var e=this.value+this.unit;return e},operate:function(t,n){return new e.Dimension(e.operate(t,this.value,n.value),this.unit||n.unit)},compare:function(t){return t instanceof e.Dimension?t.value>this.value?-1:t.value<th
is.value?1:0:-1}}}(n("../tree")),function(e){e.Directive=function(t,n){this.name=t,Array.isArray(n)?(this.ruleset=new e.Ruleset([],n),this.ruleset.allowImports=!0):this.value=n},e.Directive.prototype={toCSS:function(e,t){return this.ruleset?(this.ruleset.root=!0,this.name+(t.compress?"{":" {\n ")+this.ruleset.toCSS(e,t).trim().replace(/\n/g,"\n ")+(t.compress?"}":"\n}\n")):this.name+" "+this.value.toCSS()+";\n"},eval:function(t){var n=this;return this.ruleset&&(t.frames.unshift(this),n=new e.Directive(this.name),n.ruleset=this.ruleset.eval(t),t.frames.shift()),n},variable:function(t){return e.Ruleset.prototype.variable.call(this.ruleset,t)},find:function(){return e.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return e.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(n("../tree")),function(e){e.Element=function(t,n,r){this.combinator=t instanceof e.Combina
tor?t:new e.Combinator(t),typeof n=="string"?this.value=n.trim():n?this.value=n:this.value="",this.index=r},e.Element.prototype.eval=function(t){return new e.Element(this.combinator,this.value.eval?this.value.eval(t):this.value,this.index)},e.Element.prototype.toCSS=function(e){var t=this.value.toCSS?this.value.toCSS(e):this.value;return t==""&&this.combinator.value.charAt(0)=="&"?"":this.combinator.toCSS(e||{})+t},e.Combinator=function(e){e===" "?this.value=" ":this.value=e?e.trim():""},e.Combinator.prototype.toCSS=function(e){return{"":""," ":" ",":":" :","+":e.compress?"+":" + ","~":e.compress?"~":" ~ ",">":e.compress?">":" > "}[this.value]}}(n("../tree")),function(e){e.Expression=function(e){this.value=e},e.Expression.prot
otype={eval:function(t){return this.value.length>1?new e.Expression(this.value.map(function(e){return e.eval(t)})):this.value.length===1?this.value[0].eval(t):this},toCSS:function(e){return this.value.map(function(t){return t.toCSS?t.toCSS(e):""}).join(" ")}}}(n("../tree")),function(e){e.Import=function(t,n,r,i,s){var o=this;this.once=i,this.index=s,this._path=t,this.features=r&&new e.Value(r),t instanceof e.Quoted?this.path=/\.(le?|c)ss(\?.*)?$/.test(t.value)?t.value:t.value+".less":this.path=t.value.value||t.value,this.css=/css(\?.*)?$/.test(this.path),this.css||n.push(this.path,function(t,n,r){t&&(t.index=s),r&&o.once&&(o.skip=r),o.root=n||new e.Ruleset([],[])})},e.Import.prototype={toCSS:function(e){var t=this.features?" "+this.features.toCSS(e):"";return this.css?"@import "+this._path.toCSS()+t+";\n":""},eval:function(t){var n,r=this.features&&thi
s.features.eval(t);if(this.skip)return[];if(this.css)return this;n=new e.Ruleset([],this.root.rules.slice(0));for(var i=0;i<n.rules.length;i++)n.rules[i]instanceof e.Import&&Array.prototype.splice.apply(n.rules,[i,1].concat(n.rules[i].eval(t)));return this.features?new e.Media(n.rules,this.features.value):n.rules}}}(n("../tree")),function(e){e.JavaScript=function(e,t,n){this.escaped=n,this.expression=e,this.index=t},e.JavaScript.prototype={eval:function(t){var n,r=this,i={},s=this.expression.replace(/@\{([\w-]+)\}/g,function(n,i){return e.jsify((new e.Variable("@"+i,r.index)).eval(t))});try{s=new Function("return ("+s+")")}catch(o){throw{message:"JavaScript evaluation error: `"+s+"`",index:this.index}}for(var u in t.frames[0].variables())i[u.slice(1)]={value:t.frames[0].variables()[u].value,toJS:function(){return this.value.eval(t).toCSS()}};try{n=s.call(i)}catch(o){throw{message:"JavaScript evaluation error
: '"+o.name+": "+o.message+"'",index:this.index}}return typeof n=="string"?new e.Quoted('"'+n+'"',n,this.escaped,this.index):Array.isArray(n)?new e.Anonymous(n.join(", ")):new e.Anonymous(n)}}}(n("../tree")),function(e){e.Keyword=function(e){this.value=e},e.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value},compare:function(t){return t instanceof e.Keyword?t.value===this.value?0:1:-1}},e.True=new e.Keyword("true"),e.False=new e.Keyword("false")}(n("../tree")),function(e){e.Media=function(t,n){var r=this.emptySelectors();this.features=new e.Value(n),this.ruleset=new e.Ruleset(r,t),this.ruleset.allowImports=!0},e.Media.prototype={toCSS:function(e,t){var n=this.features.toCSS(t);return this.ruleset.root=e.length===0||e[0].multiMedia,"@media "+n+(t.compress?"{":" {\n ")+this.ruleset.toCSS(e,t).trim().replace(/\n/g,"\n "
)+(t.compress?"}":"\n}\n")},eval:function(t){t.mediaBlocks||(t.mediaBlocks=[],t.mediaPath=[]);var n=t.mediaBlocks.length;t.mediaPath.push(this),t.mediaBlocks.push(this);var r=new e.Media([],[]);return this.debugInfo&&(this.ruleset.debugInfo=this.debugInfo,r.debugInfo=this.debugInfo),r.features=this.features.eval(t),t.frames.unshift(this.ruleset),r.ruleset=this.ruleset.eval(t),t.frames.shift(),t.mediaBlocks[n]=r,t.mediaPath.pop(),t.mediaPath.length===0?r.evalTop(t):r.evalNested(t)},variable:function(t){return e.Ruleset.prototype.variable.call(this.ruleset,t)},find:function(){return e.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return e.Ruleset.prototype.rulesets.apply(this.ruleset)},emptySelectors:function(){var t=new e.Element("","&",0);return[new e.Selector([t])]},evalTop:function(t){var n=this;if(t.mediaBlocks.length>1){var r=this.emptySelectors();n=new e.Ruleset(r,t.mediaBlocks),n.multiMedia=!0}r
eturn delete t.mediaBlocks,delete t.mediaPath,n},evalNested:function(t){var n,r,i=t.mediaPath.concat([this]);for(n=0;n<i.length;n++)r=i[n].features instanceof e.Value?i[n].features.value:i[n].features,i[n]=Array.isArray(r)?r:[r];return this.features=new e.Value(this.permute(i).map(function(t){t=t.map(function(t){return t.toCSS?t:new e.Anonymous(t)});for(n=t.length-1;n>0;n--)t.splice(n,0,new e.Anonymous("and"));return new e.Expression(t)})),new e.Ruleset([],[])},permute:function(e){if(e.length===0)return[];if(e.length===1)return e[0];var t=[],n=this.permute(e.slice(1));for(var r=0;r<n.length;r++)for(var i=0;i<e[0].length;i++)t.push([e[0][i]].concat(n[r]));return t},bubbleSelectors:function(t){this.ruleset=new e.Ruleset(t.slice(0),[this.ruleset])}}}(n("../tree")),function(e){e.mixin={},e.mixin.Call=function(t,n,r,i,s){this.selector=new e.Selector(t),this.arguments=n,this.index=r,this.filename=i,this.important=s},e.mixin.Call.prototype={eval:function(e){
var t,n,r=[],i=!1;for(var s=0;s<e.frames.length;s++)if((t=e.frames[s].find(this.selector)).length>0){n=this.arguments&&this.arguments.map(function(t){return{name:t.name,value:t.value.eval(e)}});for(var o=0;o<t.length;o++)if(t[o].match(n,e))try{Array.prototype.push.apply(r,t[o].eval(e,this.arguments,this.important).rules),i=!0}catch(u){throw{message:u.message,index:this.index,filename:this.filename,stack:u.stack}}if(i)return r;throw{type:"Runtime",message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(e){return e.toCSS()}).join(", ")+")`",index:this.index,filename:this.filename}}throw{type:"Name",message:this.selector.toCSS().trim()+" is undefined",index:this.index,filename:this.filename}}},e.mixin.Definition=function(t,n,r,i,s){this.name=t,this.selectors=[new e.Selector([new e.Element(null,t)])],this.params=n,this.condition=i,this.variadic=s,t
his.arity=n.length,this.rules=r,this._lookups={},this.required=n.reduce(function(e,t){return!t.name||t.name&&!t.value?e+1:e},0),this.parent=e.Ruleset.prototype,this.frames=[]},e.mixin.Definition.prototype={toCSS:function(){return""},variable:function(e){return this.parent.variable.call(this,e)},variables:function(){return this.parent.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},evalParams:function(t,n){var r=new e.Ruleset(null,[]),i,s;for(var o=0,u,a;o<this.params.length;o++){s=n&&n[o];if(s&&s.name){r.rules.unshift(new e.Rule(s.name,s.value.eval(t))),n.splice(o,1),o--;continue}if(a=this.params[o].name)if(this.params[o].variadic&&n){i=[];for(var f=o;f<n.length;f++)i.push(n[f].value.eval(t));r.rules.unshift(new e.Rule(a,(new e.Expression(i)).eval(t)))}else{if(!(u=s&&s.value||this.params[o].value))throw{type:"Runtime",mes
sage:"wrong number of arguments for "+this.name+" ("+n.length+" for "+this.arity+")"};r.rules.unshift(new e.Rule(a,u.eval(t)))}}return r},eval:function(t,n,r){var i=this.evalParams(t,n),s,o=[],u,a;for(var f=0;f<Math.max(this.params.length,n&&n.length);f++)o.push(n[f]&&n[f].value||this.params[f].value);return i.rules.unshift(new e.Rule("@arguments",(new e.Expression(o)).eval(t))),u=r?this.rules.map(function(t){return new e.Rule(t.name,t.value,"!important",t.index)}):this.rules.slice(0),(new e.Ruleset(null,u)).eval({frames:[this,i].concat(this.frames,t.frames)})},match:function(e,t){var n=e&&e.length||0,r,i;if(!this.variadic){if(n<this.required)return!1;if(n>this.params.length)return!1;if(this.required>0&&n>this.params.length)return!1}if(this.condition&&!this.condition.eval({frames:[this.evalParams(t,e)].concat(t.frames)}))return!1;r=Math.min(n,this.arity);for(var s=0;s&l
t;r;s++)if(!this.params[s].name&&e[s].value.eval(t).toCSS()!=this.params[s].value.eval(t).toCSS())return!1;return!0}}}(n("../tree")),function(e){e.Operation=function(e,t){this.op=e.trim(),this.operands=t},e.Operation.prototype.eval=function(t){var n=this.operands[0].eval(t),r=this.operands[1].eval(t),i;if(n instanceof e.Dimension&&r instanceof e.Color){if(this.op!=="*"&&this.op!=="+")throw{name:"OperationError",message:"Can't substract or divide a color from a number"};i=r,r=n,n=i}return n.operate(this.op,r)},e.operate=function(e,t,n){switch(e){case"+":return t+n;case"-":return t-n;case"*":return t*n;case"/":return t/n}}}(n("../tree")),function(e){e.Paren=function(e){this.value=e},e.Paren.prototype={toCSS:function(e){return"("+this.value.toCSS(e)+")"},eval:function(t){return new e.Paren(this.value.eval(t))}}}(n("../tree")),function
(e){e.Quoted=function(e,t,n,r){this.escaped=n,this.value=t||"",this.quote=e.charAt(0),this.index=r},e.Quoted.prototype={toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(t){var n=this,r=this.value.replace(/`([^`]+)`/g,function(r,i){return(new e.JavaScript(i,n.index,!0)).eval(t).value}).replace(/@\{([\w-]+)\}/g,function(r,i){var s=(new e.Variable("@"+i,n.index)).eval(t);return"value"in s?s.value:s.toCSS()});return new e.Quoted(this.quote+r+this.quote,r,this.escaped,this.index)},compare:function(e){if(!e.toCSS)return-1;var t=this.toCSS(),n=e.toCSS();return t===n?0:t<n?-1:1}}}(n("../tree")),function(e){e.Ratio=function(e){this.value=e},e.Ratio.prototype={toCSS:function(e){return this.value},eval:function(){return this}}}(n("../tree")),function(e){e.Rule=function(t,n,r,i,s){this.name=t,this.value=n instanceof e.Value?n:new e.Value([n]),this.important=r?" "+r.trim():"",t
his.index=i,this.inline=s||!1,t.charAt(0)==="@"?this.variable=!0:this.variable=!1},e.Rule.prototype.toCSS=function(e){return this.variable?"":this.name+(e.compress?":":": ")+this.value.toCSS(e)+this.important+(this.inline?"":";")},e.Rule.prototype.eval=function(t){return new e.Rule(this.name,this.value.eval(t),this.important,this.index,this.inline)},e.Shorthand=function(e,t){this.a=e,this.b=t},e.Shorthand.prototype={toCSS:function(e){return this.a.toCSS(e)+"/"+this.b.toCSS(e)},eval:function(){return this}}}(n("../tree")),function(e){e.Ruleset=function(e,t,n){this.selectors=e,this.rules=t,this._lookups={},this.strictImports=n},e.Ruleset.prototype={eval:function(t){var n=this.selectors&&this.selectors.map(function(e){return e.eval(t)}),r=new e.Ruleset(n,this.rules.slice(0),this.strictImports),i=[];r.root=this.root,r.allowImports=this.allowImports,this.debugInfo&&(r.debugInfo=this.debugInfo)
,t.frames.unshift(r);if(r.root||r.allowImports||!r.strictImports){for(var s=0;s<r.rules.length;s++)r.rules[s]instanceof e.Import?i=i.concat(r.rules[s].eval(t)):i.push(r.rules[s]);r.rules=i,i=[]}for(var s=0;s<r.rules.length;s++)r.rules[s]instanceof e.mixin.Definition&&(r.rules[s].frames=t.frames.slice(0));var o=t.mediaBlocks&&t.mediaBlocks.length||0;for(var s=0;s<r.rules.length;s++)r.rules[s]instanceof e.mixin.Call?i=i.concat(r.rules[s].eval(t)):i.push(r.rules[s]);r.rules=i;for(var s=0,u;s<r.rules.length;s++)u=r.rules[s],u instanceof e.mixin.Definition||(r.rules[s]=u.eval?u.eval(t):u);t.frames.shift();if(t.mediaBlocks)for(var s=o;s<t.mediaBlocks.length;s++)t.mediaBlocks[s].bubbleSelectors(n);return r},match:function(e){return!e||e.length===0},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(t,n){return n instanceof e.Rule&&n.variable===!0&&(t[n.name]=n),t},{})},variable:function(e){re
turn this.variables()[e]},rulesets:function(){return this._rulesets?this._rulesets:this._rulesets=this.rules.filter(function(t){return t instanceof e.Ruleset||t instanceof e.mixin.Definition})},find:function(t,n){n=n||this;var r=[],i,s,o=t.toCSS();return o in this._lookups?this._lookups[o]:(this.rulesets().forEach(function(i){if(i!==n)for(var o=0;o<i.selectors.length;o++)if(s=t.match(i.selectors[o])){t.elements.length>i.selectors[o].elements.length?Array.prototype.push.apply(r,i.find(new e.Selector(t.elements.slice(1)),n)):r.push(i);break}}),this._lookups[o]=r)},toCSS:function(t,n){var r=[],i=[],s=[],o=[],u=[],a,f,l;this.root||this.joinSelectors(u,t,this.selectors);for(var c=0;c<this.rules.length;c++)l=this.rules[c],l.rules||l instanceof e.Directive||l instanceof e.Media?o.push(l.toCSS(u,n)):l instanceof e.Comment?l.silent||(this.root?o.push(l.toCSS(n)):i.push(l.toCSS(n))):l.toCSS&&!l.variable?i.push(l.toCSS(n)):l.value&&!l.variable&&i.push(l.value.t
oString());o=o.join("");if(this.root)r.push(i.join(n.compress?"":"\n"));else if(i.length>0){f=e.debugInfo(n,this),a=u.map(function(e){return e.map(function(e){return e.toCSS(n)}).join("").trim()}).join(n.compress?",":",\n");for(var c=i.length-1;c>=0;c--)s.indexOf(i[c])===-1&&s.unshift(i[c]);i=s,r.push(f+a+(n.compress?"{":" {\n ")+i.join(n.compress?"":"\n ")+(n.compress?"}":"\n}\n"))}return r.push(o),r.join("")+(n.compress?"\n":"")},joinSelectors:function(e,t,n){for(var r=0;r<n.length;r++)this.joinSelector(e,t,n[r])},joinSelector:function(t,n,r){var i,s,o,u,a,f,l,c,h,p,d,v,m,g,y;for(i=0;i<r.elements.length;i++)f=r.elements[i],f.value==="&"&&(u=!0);if(!u){if(n.length>0)for(i=0;i<n.length;i++)t.push(n[i].concat(r));else t.push([r]);return}g=[],a=[[]];for(i=0;i<r.elements.length;i++){f=r
.elements[i];if(f.value!=="&")g.push(f);else{y=[],g.length>0&&this.mergeElementsOnToSelectors(g,a);for(s=0;s<a.length;s++){l=a[s];if(n.length==0)l.length>0&&(l[0].elements=l[0].elements.slice(0),l[0].elements.push(new e.Element(f.combinator,"",0))),y.push(l);else for(o=0;o<n.length;o++)c=n[o],h=[],p=[],v=!0,l.length>0?(h=l.slice(0),m=h.pop(),d=new e.Selector(m.elements.slice(0)),v=!1):d=new e.Selector([]),c.length>1&&(p=p.concat(c.slice(1))),c.length>0&&(v=!1,d.elements.push(new e.Element(f.combinator,c[0].elements[0].value,0)),d.elements=d.elements.concat(c[0].elements.slice(1))),v||h.push(d),h=h.concat(p),y.push(h)}a=y,g=[]}}g.length>0&&this.mergeElementsOnToSelectors(g,a);for(i=0;i<a.length;i++)t.push(a[i])},mergeElementsOnToSelectors:function(t,n){var r,i;if(n.length==0){n.push([new e.Selector(t)]);return}for(r=0;r<n.length;r++)i=n[r],i.length>0?i[i.length-1]=new e.Selector(i[i.lengt
h-1].elements.concat(t)):i.push(new e.Selector(t))}}}(n("../tree")),function(e){e.Selector=function(e){this.elements=e},e.Selector.prototype.match=function(e){var t=this.elements.length,n=e.elements.length,r=Math.min(t,n);if(t<n)return!1;for(var i=0;i<r;i++)if(this.elements[i].value!==e.elements[i].value)return!1;return!0},e.Selector.prototype.eval=function(t){return new e.Selector(this.elements.map(function(e){return e.eval(t)}))},e.Selector.prototype.toCSS=function(e){return this._css?this._css:(this.elements[0].combinator.value===""?this._css=" ":this._css="",this._css+=this.elements.map(function(t){return typeof t=="string"?" "+t.trim():t.toCSS(e)}).join(""),this._css)}}(n("../tree")),function(t){t.URL=function(e,t){this.value=e,this.paths=t},t.URL.prototype={toCSS:function(){return"url("+this.value.toCSS()+")"},eval:function(n){var r=this.value.eval(n);if(this.paths.length&
gt;0&&(typeof e!="undefined"||!/^(?:[A-Za-z-]+:|\/)/.test(this.paths[0]))&&typeof r.value=="string"&&!/^(?:[a-z-]+:|\/)/.test(r.value)){var i=this.paths[0].slice(-1)==="/"?this.paths[0]:this.paths[0]+"/",s=i+(r.value.charAt(0)==="/"?r.value.slice(1):r.value);r=new t.Anonymous(s)}return new t.URL(r,this.paths)}}}(n("../tree")),function(e){e.Value=function(e){this.value=e,this.is="value"},e.Value.prototype={eval:function(t){return this.value.length===1?this.value[0].eval(t):new e.Value(this.value.map(function(e){return e.eval(t)}))},toCSS:function(e){return this.value.map(function(t){return t.toCSS(e)}).join(e.compress?",":", ")}}}(n("../tree")),function(e){e.Variable=function(e,t,n){this.name=e,this.index=t,this.file=n},e.Variable.prototype={eval:function(t){var n,r,i=this.name;i.indexOf("@@")==0&&(i="@"+(new e.Variable(i.slice(1))).e
val(t).value);if(n=e.find(t.frames,function(e){if(r=e.variable(i))return r.value.eval(t)}))return n;throw{type:"Name",message:"variable "+i+" is undefined",filename:this.file,index:this.index}}}}(n("../tree")),function(e){e.debugInfo=function(t,n){var r="";if(t.dumpLineNumbers&&!t.compress)switch(t.dumpLineNumbers){case"comments":r=e.debugInfo.asComment(n);break;case"mediaquery":r=e.debugInfo.asMediaQuery(n);break;case"all":r=e.debugInfo.asComment(n)+e.debugInfo.asMediaQuery(n)}return r},e.debugInfo.asComment=function(e){return"/* line "+e.debugInfo.lineNumber+", "+e.debugInfo.fileName+" */\n"},e.debugInfo.asMediaQuery=function(e){return'@media -sass-debug-info{filename{font-family:"'+e.debugInfo.fileName+'";}line{font-family:"'+e.debugInfo.lineNumber+'";}}\n'},e.find=function(e,t){for(var n=0,r;n<e.length;n++)if(r=t.call(e,e[n]))return r;retur
n null},e.jsify=function(e){return Array.isArray(e.value)&&e.value.length>1?"["+e.value.map(function(e){return e.toCSS(!1)}).join(", ")+"]":e.toCSS(!1)}}(n("./tree"));var s=/^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);r.env=r.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||s?"development":"production"),r.async=r.async||!1,r.fileAsync=r.fileAsync||!1,r.poll=r.poll||(s?1e3:1500),r.watch=function(){return this.watchMode=!0},r.unwatch=function(){return this.watchMode=!1};if(r.env==="development"){r.optimization=0,/!watch/.test(location.hash)&&r.watch();var o=/!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);o&&(r.dumpLineNumbers=o[1]),r.watchTimer=setInterval(function(){r.watchMode&&p(function(e,t,n,r,i){t&&m(t.toCSS(),r,i.last
Modified)})},r.poll)}else r.optimization=3;var u;try{u=typeof e.localStorage=="undefined"?null:e.localStorage}catch(a){u=null}var f=document.getElementsByTagName("link"),l=/^text\/(x-)?less$/;r.sheets=[];for(var c=0;c<f.length;c++)(f[c].rel==="stylesheet/less"||f[c].rel.match(/stylesheet/)&&f[c].type.match(l))&&r.sheets.push(f[c]);r.refresh=function(e){var t,n;t=n=new Date,p(function(e,r,i,s,o){o.local?w("loading "+s.href+" from cache."):(w("parsed "+s.href+" successfully."),m(r.toCSS(),s,o.lastModified)),w("css for "+s.href+" generated in "+(new Date-n)+"ms"),o.remaining===0&&w("css generated in "+(new Date-t)+"ms"),n=new Date},e),h()},r.refreshStyles=h,r.refresh(r.env==="development"),typeof define=="function"&&define.amd&&define("less",[],function(){return r})})(window);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistlessrhino113js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-rhino-1.1.3.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-rhino-1.1.3.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-rhino-1.1.3.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2460 @@
</span><ins>+//
+// Stub out `require` in rhino
+//
+function require(arg) {
+ return less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+ if (typeof(exports) === 'undefined') {
+ // Rhino
+ less = {};
+ tree = less.tree = {};
+ } else {
+ // Node.js
+ less = exports,
+ tree = require('less/tree');
+ }
+} else {
+ // Browser
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ mime: env && env.mime, // MIME type of .less files
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (root) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+
+ callback(root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ chunks = [];
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam,
+ inString;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = i;
+
+ if (!inString && !inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ if (c === '{' && !inString && !inParam) { level ++;
+ chunk.push(c);
+ } else if (c === '}' && !inString && !inParam) { level --;
+ chunk.push(c);
+ chunks[++j] = chunk = [];
+ } else if (c === '(' && !inString && !inParam) {
+ chunk.push(c);
+ inParam = true;
+ } else if (c === ')' && !inString && inParam) {
+ chunk.push(c);
+ inParam = false;
+ } else {
+ if (c === '"' || c === "'" || c === '`') {
+ if (! inString) {
+ inString = c;
+ } else {
+ inString = inString === c ? false : inString;
+ }
+ }
+ chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ throw {
+ type: 'Syntax',
+ message: "Missing closing `}`",
+ filename: env.filename
+ };
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [];
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ lines = input.split('\n');
+ line = getLine(e.index);
+
+ for (var n = e.index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ throw {
+ type: e.type,
+ message: e.message,
+ filename: env.filename,
+ index: e.index,
+ line: typeof(line) === 'number' ? line + 1 : null,
+ callLine: e.call && (getLine(e.call) + 1),
+ callExtract: lines[getLine(e.call)],
+ stack: e.stack,
+ column: column,
+ extract: [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ]
+ };
+ }
+ if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+
+ function getLine(index) {
+ return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ name: "ParseError",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+ if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args, index = i;
+
+ if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args, index) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+ if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value;
+
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ while (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ if (value = $(this.expression)) {
+ params.push({ name: param.name, value: value });
+ } else {
+ throw new(Error)("Expected value");
+ }
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ if (! $(',')) { break }
+ }
+ if (! $(')')) throw new(Error)("Expected )");
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset);
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^\(opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c;
+
+ c = $(this.combinator);
+ e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+ if (e) { return new(tree.Element)(c, e) }
+
+ if (c.value && c.value[0] === '&') {
+ return new(tree.Element)(c, null);
+ }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === '&') {
+ match = '&';
+ i++;
+ if(input.charAt(i) === ' ') {
+ match = '& ';
+ }
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(match);
+ } else if (c === ':' && input.charAt(i + 1) === ':') {
+ i += 2;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)('::');
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ if (match = /^([.#: \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+ i += match[0].length - 1;
+ selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+ } else {
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url)) &&
+ $(';')) {
+ return new(tree.Import)(path, imports);
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import'])) {
+ return value;
+ } else if (name = $(/^@media|@page|@-[-a-z]+/)) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (typeof(window) !== 'undefined' /* browser */ || typeof(exports) === 'undefined' /* rhino */) {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (path.charAt(0) !== '/' && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math.round(number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math.round(n);
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "math functions take numbers as parameters"
+ };
+ }
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+ this.name = name;
+ this.args = args;
+ this.index = index;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ try {
+ return tree.functions[this.name].apply(tree.functions, args);
+ } catch (e) {
+ throw { message: "error evaluating function `" + this.name + "`",
+ index: this.index };
+ }
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else if (rgb.length == 8) {
+ this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
+ this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+ this.name = name;
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+ this.value = value ? value.trim() : "";
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else if (value === '& ') {
+ this.value = '& ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ '& ' : ' ',
+ ':' : ' :',
+ '::': '::',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(' ');
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+ var that = this;
+
+ this._path = path;
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (root) {
+ if (! root) {
+ throw new(Error)("Error parsing " + that.path);
+ }
+ that.root = root;
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function () {
+ if (this.css) {
+ return "@import " + this._path.toCSS() + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset;
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return ruleset.rules;
+ }
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index };
+ }
+ }
+ }
+ throw { message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ eval: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+ for (var i = 0, val; i < this.params.length; i++) {
+ if (this.params[i].name) {
+ if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+ } else {
+ throw { message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len;
+
+ if (argsLength < this.required) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return v.value || v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + ";";
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+ ruleset.root = this.root;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > 1) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ this.joinSelectors( paths, context, this.selectors );
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ },
+
+ joinSelectors: function( paths, context, selectors ) {
+ for (var s = 0; s < selectors.length; s++) {
+ this.joinSelector(paths, context, selectors[s]);
+ }
+ },
+
+ joinSelector: function( paths, context, selector ) {
+ var before = [], after = [], beforeElements = [], afterElements = [], hasParentSelector = false, el;
+
+ for (var i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ if (el.combinator.value[0] === '&') {
+ hasParentSelector = true;
+ }
+ if(!hasParentSelector) {
+ beforeElements.push(el);
+ } else {
+ afterElements.push(el);
+ }
+ }
+
+ if(!hasParentSelector) {
+ afterElements = beforeElements;
+ beforeElements = [];
+ }
+
+ if(beforeElements.length > 0) {
+ before.push(new (tree.Selector)(beforeElements));
+ }
+ if(afterElements.length > 0) {
+ after.push(new (tree.Selector)(afterElements));
+ }
+
+ for (var c = 0; c < context.length; c++) {
+ paths.push(before.concat(context[c]).concat(after));
+ }
+ }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ if (this.elements[0].value === other.elements[0].value) {
+ return true;
+ } else {
+ return false;
+ }
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { message: "variable " + name + " is undefined",
+ index: this.index };
+ }
+ }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+require('less/tree').jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+var name;
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var sheetName = name.slice(0, name.lastIndexOf('/') + 1) + sheet.href;
+ var input = readFile(sheetName);
+ var parser = new less.Parser();
+ parser.parse(input, function (e, root) {
+ if (e) {
+ print("Error: " + e);
+ quit(1);
+ }
+ callback(root, sheet, { local: false, lastModified: 0, remaining: remaining });
+ });
+
+ // callback({}, sheet, { local: true, remaining: remaining });
+}
+
+function writeFile(filename, content) {
+ var fstream = new java.io.FileWriter(filename);
+ var out = new java.io.BufferedWriter(fstream);
+ out.write(content);
+ out.close();
+}
+
+// Command line integration via Rhino
+(function (args) {
+ name = args[0];
+ var output = args[1];
+
+ if (!name) {
+ print('No files present in the fileset; Check your pattern match in build.xml');
+ quit(1);
+ }
+ path = name.split("/");path.pop();path=path.join("/")
+
+ var input = readFile(name);
+
+ if (!input) {
+ print('lesscss: couldn\'t open file ' + name);
+ quit(1);
+ }
+
+ var result;
+ var parser = new less.Parser();
+ parser.parse(input, function (e, root) {
+ if (e) {
+ quit(1);
+ } else {
+ result = root.toCSS();
+ if (output) {
+ writeFile(output, result);
+ print("Written to " + output);
+ } else {
+ print(result);
+ }
+ quit(0);
+ }
+ });
+ print("done");
+}(arguments));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessdistlessrhino115js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-rhino-1.1.5.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-rhino-1.1.5.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/dist/less-rhino-1.1.5.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2481 @@
</span><ins>+//
+// Stub out `require` in rhino
+//
+function require(arg) {
+ return less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+ Array.isArray = function(obj) {
+ return Object.prototype.toString.call(obj) === "[object Array]" ||
+ (obj instanceof Array);
+ };
+}
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function(block, thisObject) {
+ var len = this.length >>> 0;
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ block.call(thisObject, this[i], i, this);
+ }
+ }
+ };
+}
+if (!Array.prototype.map) {
+ Array.prototype.map = function(fun /*, thisp*/) {
+ var len = this.length >>> 0;
+ var res = new Array(len);
+ var thisp = arguments[1];
+
+ for (var i = 0; i < len; i++) {
+ if (i in this) {
+ res[i] = fun.call(thisp, this[i], i, this);
+ }
+ }
+ return res;
+ };
+}
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (block /*, thisp */) {
+ var values = [];
+ var thisp = arguments[1];
+ for (var i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
+ values.push(this[i]);
+ }
+ }
+ return values;
+ };
+}
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function(fun /*, initial*/) {
+ var len = this.length >>> 0;
+ var i = 0;
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) throw new TypeError();
+
+ if (arguments.length >= 2) {
+ var rv = arguments[1];
+ } else {
+ do {
+ if (i in this) {
+ rv = this[i++];
+ break;
+ }
+ // if array contains no values, no initial value to return
+ if (++i >= len) throw new TypeError();
+ } while (true);
+ }
+ for (; i < len; i++) {
+ if (i in this) {
+ rv = fun.call(null, rv, this[i], i, this);
+ }
+ }
+ return rv;
+ };
+}
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+ var length = this.length;
+ var i = arguments[1] || 0;
+
+ if (!length) return -1;
+ if (i >= length) return -1;
+ if (i < 0) i += length;
+
+ for (; i < length; i++) {
+ if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+ if (value === this[i]) return i;
+ }
+ return -1;
+ };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+ Object.keys = function (object) {
+ var keys = [];
+ for (var name in object) {
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
+ keys.push(name);
+ }
+ }
+ return keys;
+ };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+ // Rhino
+ // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+ less = {};
+ tree = less.tree = {};
+ less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+ // Node.js
+ less = exports,
+ tree = require('./tree');
+ less.mode = 'rhino';
+} else {
+ // Browser
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+ less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ mime: env && env.mime, // MIME type of .less files
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (root) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+ that.files[path] = root; // Store the root
+
+ callback(root);
+
+ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, c, index, endIndex, k, mem;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ mem = i += length;
+ endIndex = i + chunks[j].length - length;
+
+ while (i < endIndex) {
+ c = input.charCodeAt(i);
+ if (! (c === 32 || c === 10 || c === 9)) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ chunks = [];
+ input = str.replace(/\r\n/g, '\n');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /[^"'`\{\}\/\(\)]+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam,
+ inString;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = i;
+
+ if (!inString && !inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ if (c === '{' && !inString && !inParam) { level ++;
+ chunk.push(c);
+ } else if (c === '}' && !inString && !inParam) { level --;
+ chunk.push(c);
+ chunks[++j] = chunk = [];
+ } else if (c === '(' && !inString && !inParam) {
+ chunk.push(c);
+ inParam = true;
+ } else if (c === ')' && !inString && inParam) {
+ chunk.push(c);
+ inParam = false;
+ } else {
+ if (c === '"' || c === "'" || c === '`') {
+ if (! inString) {
+ inString = c;
+ } else {
+ inString = inString === c ? false : inString;
+ }
+ }
+ chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ throw {
+ type: 'Syntax',
+ message: "Missing closing `}`",
+ filename: env.filename
+ };
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [];
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false });
+ } catch (e) {
+ lines = input.split('\n');
+ line = getLine(e.index);
+
+ for (var n = e.index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ throw {
+ type: e.type,
+ message: e.message,
+ filename: env.filename,
+ index: e.index,
+ line: typeof(line) === 'number' ? line + 1 : null,
+ callLine: e.call && (getLine(e.call) + 1),
+ callExtract: lines[getLine(e.call)],
+ stack: e.stack,
+ column: column,
+ extract: [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ]
+ };
+ }
+ if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+
+ function getLine(index) {
+ return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ name: "ParseError",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function () { callback(error, root) };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+ if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) { return new(tree.Keyword)(k) }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, args, index = i;
+
+ if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+ name = name[1].toLowerCase();
+
+ if (name === 'url') { return null }
+ else { i += name.length }
+
+ if (name === 'alpha') { return $(this.alpha) }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args, index) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+ if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+ return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ dataURI: function () {
+ var obj;
+
+ if ($(/^data:/)) {
+ obj = {};
+ obj.mime = $(/^[^\/]+\/[^,;)]+/) || '';
+ obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+ obj.base64 = $(/^;\s*base64/) || '';
+ obj.data = $(/^,\s*[^)]+/);
+
+ if (obj.data) { return obj }
+ }
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+ if (s !== '.' && s !== '#') { return }
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e, i));
+ c = $('>');
+ }
+ $('(') && (args = $(this.entities.arguments)) && $(')');
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index);
+ }
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value;
+
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ while (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ if (value = $(this.expression)) {
+ params.push({ name: param.name, value: value });
+ } else {
+ throw new(Error)("Expected value");
+ }
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ if (! $(',')) { break }
+ }
+ if (! $(')')) throw new(Error)("Expected )");
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset);
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^\(opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c;
+
+ c = $(this.combinator);
+ e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+ $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+ if (e) { return new(tree.Element)(c, e, i) }
+
+ if (c.value && c.value.charAt(0) === '&') {
+ return new(tree.Element)(c, null, i);
+ }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(c);
+ } else if (c === '&') {
+ match = '&';
+ i++;
+ if(input.charAt(i) === ' ') {
+ match = '& ';
+ }
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)(match);
+ } else if (c === ':' && input.charAt(i + 1) === ':') {
+ i += 2;
+ while (input.charAt(i) === ' ') { i++ }
+ return new(tree.Combinator)('::');
+ } else if (input.charAt(i - 1) === ' ') {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match;
+ save();
+
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ return new(tree.Ruleset)(selectors, rules);
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path;
+ if ($(/^@import\s+/) &&
+ (path = $(this.entities.quoted) || $(this.entities.url)) &&
+ $(';')) {
+ return new(tree.Import)(path, imports);
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, types;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import'])) {
+ return value;
+ } else if (name = $(/^@media|@page/) || $(/^@(?:-webkit-|-moz-)?keyframes/)) {
+ types = ($(/^[^{]+/) || '').trim();
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name + " " + types, rules);
+ }
+ } else if (name = $(/^@[-a-z]+/)) {
+ if (name === '@font-face') {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (path.charAt(0) !== '/' && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+ };
+}
+
+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fade: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a = amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math.round(number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math.round(n);
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "math functions take numbers as parameters"
+ };
+ }
+ },
+ argb: function (color) {
+ return new(tree.Anonymous)(color.toARGB());
+
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+ this.name = name;
+ this.args = args;
+ this.index = index;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ try {
+ return tree.functions[this.name].apply(tree.functions, args);
+ } catch (e) {
+ throw { message: "error evaluating function `" + this.name + "`",
+ index: this.index };
+ }
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ },
+ toARGB: function () {
+ var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+ return '#' + argb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+ this.name = name;
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ env.frames.unshift(this);
+ this.ruleset = this.ruleset && this.ruleset.eval(env);
+ env.frames.shift();
+ return this;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+ this.value = value ? value.trim() : "";
+ this.index = index;
+};
+tree.Element.prototype.toCSS = function (env) {
+ return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else if (value === '& ') {
+ this.value = '& ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ '&' : '',
+ '& ' : ' ',
+ ':' : ' :',
+ '::': '::',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(' ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+ var that = this;
+
+ this._path = path;
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css(\?.*)?$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (root) {
+ if (! root) {
+ throw new(Error)("Error parsing " + that.path);
+ }
+ that.root = root;
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function () {
+ if (this.css) {
+ return "@import " + this._path.toCSS() + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset;
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return ruleset.rules;
+ }
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index };
+ }
+ }
+ }
+ throw { message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ eval: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+ for (var i = 0, val; i < this.params.length; i++) {
+ if (this.params[i].name) {
+ if (val = (args && args[i]) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+ } else {
+ throw { message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push(args[i] || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len;
+
+ if (argsLength < this.required) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return v.value || v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + ";";
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+ ruleset.root = this.root;
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ Array.prototype.splice
+ .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > rule.selectors[j].elements.length) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ rule;
+
+ if (! this.root) {
+ if (context.length === 0) {
+ paths = this.selectors.map(function (s) { return [s] });
+ } else {
+ this.joinSelectors( paths, context, this.selectors );
+ }
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+ css.push(selector,
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ },
+
+ joinSelectors: function (paths, context, selectors) {
+ for (var s = 0; s < selectors.length; s++) {
+ this.joinSelector(paths, context, selectors[s]);
+ }
+ },
+
+ joinSelector: function (paths, context, selector) {
+ var before = [], after = [], beforeElements = [],
+ afterElements = [], hasParentSelector = false, el;
+
+ for (var i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ if (el.combinator.value.charAt(0) === '&') {
+ hasParentSelector = true;
+ }
+ if (hasParentSelector) afterElements.push(el);
+ else beforeElements.push(el);
+ }
+
+ if (! hasParentSelector) {
+ afterElements = beforeElements;
+ beforeElements = [];
+ }
+
+ if (beforeElements.length > 0) {
+ before.push(new(tree.Selector)(beforeElements));
+ }
+
+ if (afterElements.length > 0) {
+ after.push(new(tree.Selector)(afterElements));
+ }
+
+ for (var c = 0; c < context.length; c++) {
+ paths.push(before.concat(context[c]).concat(after));
+ }
+ }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+ if (this.elements[0].combinator.value === "") {
+ this.elements[0].combinator.value = ' ';
+ }
+};
+tree.Selector.prototype.match = function (other) {
+ var len = this.elements.length,
+ olen = other.elements.length,
+ max = Math.min(len, olen);
+
+ if (len < olen) {
+ return false;
+ } else {
+ for (var i = 0; i < max; i++) {
+ if (this.elements[i].value !== other.elements[i].value) {
+ return false;
+ }
+ }
+ }
+ return true;
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ return this._css = this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+ if (val.data) {
+ this.attrs = val;
+ } else {
+ // Add the base path if the URL is relative and we are in the browser
+ if (!/^(?:https?:\/\/|file:\/\/|data:)?/.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+ val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ }
+ this.value = val;
+ this.paths = paths;
+ }
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+ : this.value.toCSS()) + ")";
+ },
+ eval: function (ctx) {
+ return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { message: "variable " + name + " is undefined",
+ index: this.index };
+ }
+ }
+};
+
+})(require('../tree'));
+require('./tree').find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+require('./tree').jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+var name;
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var sheetName = name.slice(0, name.lastIndexOf('/') + 1) + sheet.href;
+ var input = readFile(sheetName);
+ var parser = new less.Parser();
+ parser.parse(input, function (e, root) {
+ if (e) {
+ print("Error: " + e);
+ quit(1);
+ }
+ callback(root, sheet, { local: false, lastModified: 0, remaining: remaining });
+ });
+
+ // callback({}, sheet, { local: true, remaining: remaining });
+}
+
+function writeFile(filename, content) {
+ var fstream = new java.io.FileWriter(filename);
+ var out = new java.io.BufferedWriter(fstream);
+ out.write(content);
+ out.close();
+}
+
+// Command line integration via Rhino
+(function (args) {
+ name = args[0];
+ var output = args[1];
+
+ if (!name) {
+ print('No files present in the fileset; Check your pattern match in build.xml');
+ quit(1);
+ }
+ path = name.split("/");path.pop();path=path.join("/")
+
+ var input = readFile(name);
+
+ if (!input) {
+ print('lesscss: couldn\'t open file ' + name);
+ quit(1);
+ }
+
+ var result;
+ var parser = new less.Parser();
+ parser.parse(input, function (e, root) {
+ if (e) {
+ quit(1);
+ } else {
+ result = root.toCSS();
+ if (output) {
+ writeFile(output, result);
+ print("Written to " + output);
+ } else {
+ print(result);
+ }
+ quit(0);
+ }
+ });
+ print("done");
+}(arguments));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblessbrowserjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/browser.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/browser.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/browser.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,394 @@
</span><ins>+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+ location.hostname == '0.0.0.0' ||
+ location.hostname == 'localhost' ||
+ location.port.length > 0 ||
+ isFileProtocol ? 'development'
+ : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = less.async || false;
+less.fileAsync = less.fileAsync || false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+ less.optimization = 0;
+
+ if (/!watch/.test(location.hash)) {
+ less.watch();
+ }
+ var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);
+ if (dumpLineNumbers) {
+ less.dumpLineNumbers = dumpLineNumbers[1];
+ }
+ less.watchTimer = setInterval(function () {
+ if (less.watchMode) {
+ loadStyleSheets(function (e, root, _, sheet, env) {
+ if (root) {
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ });
+ }
+ }, less.poll);
+} else {
+ less.optimization = 3;
+}
+
+var cache;
+
+try {
+ cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+ cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+ if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+ (links[i].type.match(typePattern)))) {
+ less.sheets.push(links[i]);
+ }
+}
+
+
+less.refresh = function (reload) {
+ var startTime, endTime;
+ startTime = endTime = new(Date);
+
+ loadStyleSheets(function (e, root, _, sheet, env) {
+ if (env.local) {
+ log("loading " + sheet.href + " from cache.");
+ } else {
+ log("parsed " + sheet.href + " successfully.");
+ createCSS(root.toCSS(), sheet, env.lastModified);
+ }
+ log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+ (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+ endTime = new(Date);
+ }, reload);
+
+ loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+ var styles = document.getElementsByTagName('style');
+ for (var i = 0; i < styles.length; i++) {
+ if (styles[i].type.match(typePattern)) {
+ new(less.Parser)({
+ filename: document.location.href.replace(/#.*$/, ''),
+ dumpLineNumbers: less.dumpLineNumbers
+ }).parse(styles[i].innerHTML || '', function (e, tree) {
+ var css = tree.toCSS();
+ var style = styles[i];
+ style.type = 'text/css';
+ if (style.styleSheet) {
+ style.styleSheet.cssText = css;
+ } else {
+ style.innerHTML = css;
+ }
+ });
+ }
+ }
+}
+
+function loadStyleSheets(callback, reload) {
+ for (var i = 0; i < less.sheets.length; i++) {
+ loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+ }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var contents = sheet.contents || {}; // Passing a ref to top importing parser content cache trough 'sheet' arg.
+ var url = window.location.href.replace(/[#?].*$/, '');
+ var href = sheet.href.replace(/\?.*$/, '');
+ var css = cache && cache.getItem(href);
+ var timestamp = cache && cache.getItem(href + ':timestamp');
+ var styles = { css: css, timestamp: timestamp };
+
+ // Stylesheets in IE don't always return the full path
+ if (! /^[a-z-]+:/.test(href)) {
+ if (href.charAt(0) == "/") {
+ href = window.location.protocol + "//" + window.location.host + href;
+ } else {
+ href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+ }
+ }
+ xhr(sheet.href, sheet.type, function (data, lastModified) {
+ if (!reload && styles && lastModified &&
+ (new(Date)(lastModified).valueOf() ===
+ new(Date)(styles.timestamp).valueOf())) {
+ // Use local copy
+ createCSS(styles.css, sheet);
+ callback(null, null, data, sheet, { local: true, remaining: remaining });
+ } else {
+ // Use remote copy (re-parse)
+ try {
+ contents[href] = data; // Updating top importing parser content cache
+ new(less.Parser)({
+ optimization: less.optimization,
+ paths: [href.replace(/[\w\.-]+$/, '')],
+ mime: sheet.type,
+ filename: href,
+ 'contents': contents, // Passing top importing parser content cache ref down.
+ dumpLineNumbers: less.dumpLineNumbers
+ }).parse(data, function (e, root) {
+ if (e) { return error(e, href) }
+ try {
+ callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+ removeNode(document.getElementById('less-error-message:' + extractId(href)));
+ } catch (e) {
+ error(e, href);
+ }
+ });
+ } catch (e) {
+ error(e, href);
+ }
+ }
+ }, function (status, url) {
+ throw new(Error)("Couldn't load " + url + " (" + status + ")");
+ });
+}
+
+function extractId(href) {
+ return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\?.*$/, '' ) // Remove query
+ .replace(/\.[^\.\/]+$/, '' ) // Remove file extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+ var css;
+
+ // Strip the query-string
+ var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || extractId(href));
+
+ // If the stylesheet doesn't exist, create a new node
+ if ((css = document.getElementById(id)) === null) {
+ css = document.createElement('style');
+ css.type = 'text/css';
+ if( sheet.media ){ css.media = sheet.media; }
+ css.id = id;
+ var nextEl = sheet && sheet.nextSibling || null;
+ document.getElementsByTagName('head')[0].insertBefore(css, nextEl);
+ }
+
+ if (css.styleSheet) { // IE
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ } else {
+ (function (node) {
+ if (css.childNodes.length > 0) {
+ if (css.firstChild.nodeValue !== node.nodeValue) {
+ css.replaceChild(node, css.firstChild);
+ }
+ } else {
+ css.appendChild(node);
+ }
+ })(document.createTextNode(styles));
+ }
+
+ // Don't update the local store if the file wasn't modified
+ if (lastModified && cache) {
+ log('saving ' + href + ' to cache.');
+ try {
+ cache.setItem(href, styles);
+ cache.setItem(href + ':timestamp', lastModified);
+ } catch(e) {
+ //TODO - could do with adding more robust error handling
+ log('failed to save');
+ }
+ }
+}
+
+function xhr(url, type, callback, errback) {
+ var xhr = getXMLHttpRequest();
+ var async = isFileProtocol ? less.fileAsync : less.async;
+
+ if (typeof(xhr.overrideMimeType) === 'function') {
+ xhr.overrideMimeType('text/css');
+ }
+ xhr.open('GET', url, async);
+ xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+ xhr.send(null);
+
+ if (isFileProtocol && !less.fileAsync) {
+ if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+ callback(xhr.responseText);
+ } else {
+ errback(xhr.status, url);
+ }
+ } else if (async) {
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ handleResponse(xhr, callback, errback);
+ }
+ };
+ } else {
+ handleResponse(xhr, callback, errback);
+ }
+
+ function handleResponse(xhr, callback, errback) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ callback(xhr.responseText,
+ xhr.getResponseHeader("Last-Modified"));
+ } else if (typeof(errback) === 'function') {
+ errback(xhr.status, url);
+ }
+ }
+}
+
+function getXMLHttpRequest() {
+ if (window.XMLHttpRequest) {
+ return new(XMLHttpRequest);
+ } else {
+ try {
+ return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+ } catch (e) {
+ log("browser doesn't support AJAX.");
+ return null;
+ }
+ }
+}
+
+function removeNode(node) {
+ return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+ if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+ var id = 'less-error-message:' + extractId(href);
+ var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+ var elem = document.createElement('div'), timer, content, error = [];
+ var filename = e.filename || href;
+ var filenameNoPath = filename.match(/([^\/]+)$/)[1];
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p>in <a href="' + filename + '">' + filenameNoPath + "</a> ";
+
+ var errorline = function (e, i, classname) {
+ if (e.extract[i]) {
+ error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
+ .replace(/\{class\}/, classname)
+ .replace(/\{content\}/, e.extract[i]));
+ }
+ };
+
+ if (e.stack) {
+ content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+ } else if (e.extract) {
+ errorline(e, 0, '');
+ errorline(e, 1, 'line');
+ errorline(e, 2, '');
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ '<ul>' + error.join('') + '</ul>';
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ createCSS([
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #dd6666;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.line {',
+ 'color: #ff0000;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (less.env == 'development') {
+ timer = setInterval(function () {
+ if (document.body) {
+ if (document.getElementById(id)) {
+ document.body.replaceChild(elem, document.getElementById(id));
+ } else {
+ document.body.insertBefore(elem, document.body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+}
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesscolorsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/colors.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/colors.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/colors.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,152 @@
</span><ins>+(function (tree) {
+ tree.colors = {
+ 'aliceblue':'#f0f8ff',
+ 'antiquewhite':'#faebd7',
+ 'aqua':'#00ffff',
+ 'aquamarine':'#7fffd4',
+ 'azure':'#f0ffff',
+ 'beige':'#f5f5dc',
+ 'bisque':'#ffe4c4',
+ 'black':'#000000',
+ 'blanchedalmond':'#ffebcd',
+ 'blue':'#0000ff',
+ 'blueviolet':'#8a2be2',
+ 'brown':'#a52a2a',
+ 'burlywood':'#deb887',
+ 'cadetblue':'#5f9ea0',
+ 'chartreuse':'#7fff00',
+ 'chocolate':'#d2691e',
+ 'coral':'#ff7f50',
+ 'cornflowerblue':'#6495ed',
+ 'cornsilk':'#fff8dc',
+ 'crimson':'#dc143c',
+ 'cyan':'#00ffff',
+ 'darkblue':'#00008b',
+ 'darkcyan':'#008b8b',
+ 'darkgoldenrod':'#b8860b',
+ 'darkgray':'#a9a9a9',
+ 'darkgrey':'#a9a9a9',
+ 'darkgreen':'#006400',
+ 'darkkhaki':'#bdb76b',
+ 'darkmagenta':'#8b008b',
+ 'darkolivegreen':'#556b2f',
+ 'darkorange':'#ff8c00',
+ 'darkorchid':'#9932cc',
+ 'darkred':'#8b0000',
+ 'darksalmon':'#e9967a',
+ 'darkseagreen':'#8fbc8f',
+ 'darkslateblue':'#483d8b',
+ 'darkslategray':'#2f4f4f',
+ 'darkslategrey':'#2f4f4f',
+ 'darkturquoise':'#00ced1',
+ 'darkviolet':'#9400d3',
+ 'deeppink':'#ff1493',
+ 'deepskyblue':'#00bfff',
+ 'dimgray':'#696969',
+ 'dimgrey':'#696969',
+ 'dodgerblue':'#1e90ff',
+ 'firebrick':'#b22222',
+ 'floralwhite':'#fffaf0',
+ 'forestgreen':'#228b22',
+ 'fuchsia':'#ff00ff',
+ 'gainsboro':'#dcdcdc',
+ 'ghostwhite':'#f8f8ff',
+ 'gold':'#ffd700',
+ 'goldenrod':'#daa520',
+ 'gray':'#808080',
+ 'grey':'#808080',
+ 'green':'#008000',
+ 'greenyellow':'#adff2f',
+ 'honeydew':'#f0fff0',
+ 'hotpink':'#ff69b4',
+ 'indianred':'#cd5c5c',
+ 'indigo':'#4b0082',
+ 'ivory':'#fffff0',
+ 'khaki':'#f0e68c',
+ 'lavender':'#e6e6fa',
+ 'lavenderblush':'#fff0f5',
+ 'lawngreen':'#7cfc00',
+ 'lemonchiffon':'#fffacd',
+ 'lightblue':'#add8e6',
+ 'lightcoral':'#f08080',
+ 'lightcyan':'#e0ffff',
+ 'lightgoldenrodyellow':'#fafad2',
+ 'lightgray':'#d3d3d3',
+ 'lightgrey':'#d3d3d3',
+ 'lightgreen':'#90ee90',
+ 'lightpink':'#ffb6c1',
+ 'lightsalmon':'#ffa07a',
+ 'lightseagreen':'#20b2aa',
+ 'lightskyblue':'#87cefa',
+ 'lightslategray':'#778899',
+ 'lightslategrey':'#778899',
+ 'lightsteelblue':'#b0c4de',
+ 'lightyellow':'#ffffe0',
+ 'lime':'#00ff00',
+ 'limegreen':'#32cd32',
+ 'linen':'#faf0e6',
+ 'magenta':'#ff00ff',
+ 'maroon':'#800000',
+ 'mediumaquamarine':'#66cdaa',
+ 'mediumblue':'#0000cd',
+ 'mediumorchid':'#ba55d3',
+ 'mediumpurple':'#9370d8',
+ 'mediumseagreen':'#3cb371',
+ 'mediumslateblue':'#7b68ee',
+ 'mediumspringgreen':'#00fa9a',
+ 'mediumturquoise':'#48d1cc',
+ 'mediumvioletred':'#c71585',
+ 'midnightblue':'#191970',
+ 'mintcream':'#f5fffa',
+ 'mistyrose':'#ffe4e1',
+ 'moccasin':'#ffe4b5',
+ 'navajowhite':'#ffdead',
+ 'navy':'#000080',
+ 'oldlace':'#fdf5e6',
+ 'olive':'#808000',
+ 'olivedrab':'#6b8e23',
+ 'orange':'#ffa500',
+ 'orangered':'#ff4500',
+ 'orchid':'#da70d6',
+ 'palegoldenrod':'#eee8aa',
+ 'palegreen':'#98fb98',
+ 'paleturquoise':'#afeeee',
+ 'palevioletred':'#d87093',
+ 'papayawhip':'#ffefd5',
+ 'peachpuff':'#ffdab9',
+ 'peru':'#cd853f',
+ 'pink':'#ffc0cb',
+ 'plum':'#dda0dd',
+ 'powderblue':'#b0e0e6',
+ 'purple':'#800080',
+ 'red':'#ff0000',
+ 'rosybrown':'#bc8f8f',
+ 'royalblue':'#4169e1',
+ 'saddlebrown':'#8b4513',
+ 'salmon':'#fa8072',
+ 'sandybrown':'#f4a460',
+ 'seagreen':'#2e8b57',
+ 'seashell':'#fff5ee',
+ 'sienna':'#a0522d',
+ 'silver':'#c0c0c0',
+ 'skyblue':'#87ceeb',
+ 'slateblue':'#6a5acd',
+ 'slategray':'#708090',
+ 'slategrey':'#708090',
+ 'snow':'#fffafa',
+ 'springgreen':'#00ff7f',
+ 'steelblue':'#4682b4',
+ 'tan':'#d2b48c',
+ 'teal':'#008080',
+ 'thistle':'#d8bfd8',
+ 'tomato':'#ff6347',
+ // 'transparent':'rgba(0,0,0,0)',
+ 'turquoise':'#40e0d0',
+ 'violet':'#ee82ee',
+ 'wheat':'#f5deb3',
+ 'white':'#ffffff',
+ 'whitesmoke':'#f5f5f5',
+ 'yellow':'#ffff00',
+ 'yellowgreen':'#9acd32'
+ };
+})(require('./tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesscssminjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/cssmin.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/cssmin.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/cssmin.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,355 @@
</span><ins>+/**
+ * cssmin.js
+ * Author: Stoyan Stefanov - http://phpied.com/
+ * This is a JavaScript port of the CSS minification tool
+ * distributed with YUICompressor, itself a port
+ * of the cssmin utility by Isaac Schlueter - http://foohack.com/
+ * Permission is hereby granted to use the JavaScript version under the same
+ * conditions as the YUICompressor (original YUICompressor note below).
+ */
+
+/*
+* YUI Compressor
+* http://developer.yahoo.com/yui/compressor/
+* Author: Julien Lecomte - http://www.julienlecomte.net/
+* Copyright (c) 2011 Yahoo! Inc. All rights reserved.
+* The copyrights embodied in the content of this file are licensed
+* by Yahoo! Inc. under the BSD (revised) open source license.
+*/
+var YAHOO = YAHOO || {};
+YAHOO.compressor = YAHOO.compressor || {};
+
+/**
+ * Utility method to replace all data urls with tokens before we start
+ * compressing, to avoid performance issues running some of the subsequent
+ * regexes against large strings chunks.
+ *
+ * @private
+ * @method _extractDataUrls
+ * @param {String} css The input css
+ * @param {Array} The global array of tokens to preserve
+ * @returns String The processed css
+ */
+YAHOO.compressor._extractDataUrls = function (css, preservedTokens) {
+
+ // Leave data urls alone to increase parse performance.
+ var maxIndex = css.length - 1,
+ appendIndex = 0,
+ startIndex,
+ endIndex,
+ terminator,
+ foundTerminator,
+ sb = [],
+ m,
+ preserver,
+ token,
+ pattern = /url\(\s*(["']?)data\:/g;
+
+ // Since we need to account for non-base64 data urls, we need to handle
+ // ' and ) being part of the data string. Hence switching to indexOf,
+ // to determine whether or not we have matching string terminators and
+ // handling sb appends directly, instead of using matcher.append* methods.
+
+ while ((m = pattern.exec(css)) !== null) {
+
+ startIndex = m.index + 4; // "url(".length()
+ terminator = m[1]; // ', " or empty (not quoted)
+
+ if (terminator.length === 0) {
+ terminator = ")";
+ }
+
+ foundTerminator = false;
+
+ endIndex = pattern.lastIndex - 1;
+
+ while(foundTerminator === false && endIndex+1 <= maxIndex) {
+ endIndex = css.indexOf(terminator, endIndex + 1);
+
+ // endIndex == 0 doesn't really apply here
+ if ((endIndex > 0) && (css.charAt(endIndex - 1) !== '\\')) {
+ foundTerminator = true;
+ if (")" != terminator) {
+ endIndex = css.indexOf(")", endIndex);
+ }
+ }
+ }
+
+ // Enough searching, start moving stuff over to the buffer
+ sb.push(css.substring(appendIndex, m.index));
+
+ if (foundTerminator) {
+ token = css.substring(startIndex, endIndex);
+ token = token.replace(/\s+/g, "");
+ preservedTokens.push(token);
+
+ preserver = "url(___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___)";
+ sb.push(preserver);
+
+ appendIndex = endIndex + 1;
+ } else {
+ // No end terminator found, re-add the whole match. Should we throw/warn here?
+ sb.push(css.substring(m.index, pattern.lastIndex));
+ appendIndex = pattern.lastIndex;
+ }
+ }
+
+ sb.push(css.substring(appendIndex));
+
+ return sb.join("");
+};
+
+/**
+ * Utility method to compress hex color values of the form #AABBCC to #ABC.
+ *
+ * DOES NOT compress CSS ID selectors which match the above pattern (which would break things).
+ * e.g. #AddressForm { ... }
+ *
+ * DOES NOT compress IE filters, which have hex color values (which would break things).
+ * e.g. filter: chroma(color="#FFFFFF");
+ *
+ * DOES NOT compress invalid hex values.
+ * e.g. background-color: #aabbccdd
+ *
+ * @private
+ * @method _compressHexColors
+ * @param {String} css The input css
+ * @returns String The processed css
+ */
+YAHOO.compressor._compressHexColors = function(css) {
+
+ // Look for hex colors inside { ... } (to avoid IDs) and which don't have a =, or a " in front of them (to avoid filters)
+ var pattern = /(\=\s*?["']?)?#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])(\}|[^0-9a-f{][^{]*?\})/gi,
+ m,
+ index = 0,
+ isFilter,
+ sb = [];
+
+ while ((m = pattern.exec(css)) !== null) {
+
+ sb.push(css.substring(index, m.index));
+
+ isFilter = m[1];
+
+ if (isFilter) {
+ // Restore, maintain case, otherwise filter will break
+ sb.push(m[1] + "#" + (m[2] + m[3] + m[4] + m[5] + m[6] + m[7]));
+ } else {
+ if (m[2].toLowerCase() == m[3].toLowerCase() &&
+ m[4].toLowerCase() == m[5].toLowerCase() &&
+ m[6].toLowerCase() == m[7].toLowerCase()) {
+
+ // Compress.
+ sb.push("#" + (m[3] + m[5] + m[7]).toLowerCase());
+ } else {
+ // Non compressible color, restore but lower case.
+ sb.push("#" + (m[2] + m[3] + m[4] + m[5] + m[6] + m[7]).toLowerCase());
+ }
+ }
+
+ index = pattern.lastIndex = pattern.lastIndex - m[8].length;
+ }
+
+ sb.push(css.substring(index));
+
+ return sb.join("");
+};
+
+YAHOO.compressor.cssmin = function (css, linebreakpos) {
+
+ var startIndex = 0,
+ endIndex = 0,
+ i = 0, max = 0,
+ preservedTokens = [],
+ comments = [],
+ token = '',
+ totallen = css.length,
+ placeholder = '';
+
+ css = this._extractDataUrls(css, preservedTokens);
+
+ // collect all comment blocks...
+ while ((startIndex = css.indexOf("/*", startIndex)) >= 0) {
+ endIndex = css.indexOf("*/", startIndex + 2);
+ if (endIndex < 0) {
+ endIndex = totallen;
+ }
+ token = css.slice(startIndex + 2, endIndex);
+ comments.push(token);
+ css = css.slice(0, startIndex + 2) + "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + (comments.length - 1) + "___" + css.slice(endIndex);
+ startIndex += 2;
+ }
+
+ // preserve strings so their content doesn't get accidentally minified
+ css = css.replace(/("([^\\"]|\\.|\\)*")|('([^\\']|\\.|\\)*')/g, function (match) {
+ var i, max, quote = match.substring(0, 1);
+
+ match = match.slice(1, -1);
+
+ // maybe the string contains a comment-like substring?
+ // one, maybe more? put'em back then
+ if (match.indexOf("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_") >= 0) {
+ for (i = 0, max = comments.length; i < max; i = i + 1) {
+ match = match.replace("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___", comments[i]);
+ }
+ }
+
+ // minify alpha opacity in filter strings
+ match = match.replace(/progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/gi, "alpha(opacity=");
+
+ preservedTokens.push(match);
+ return quote + "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___" + quote;
+ });
+
+ // strings are safe, now wrestle the comments
+ for (i = 0, max = comments.length; i < max; i = i + 1) {
+
+ token = comments[i];
+ placeholder = "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___";
+
+ // ! in the first position of the comment means preserve
+ // so push to the preserved tokens keeping the !
+ if (token.charAt(0) === "!") {
+ preservedTokens.push(token);
+ css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___");
+ continue;
+ }
+
+ // \ in the last position looks like hack for Mac/IE5
+ // shorten that to /*\*/ and the next one to /**/
+ if (token.charAt(token.length - 1) === "\\") {
+ preservedTokens.push("\\");
+ css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___");
+ i = i + 1; // attn: advancing the loop
+ preservedTokens.push("");
+ css = css.replace("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___", "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___");
+ continue;
+ }
+
+ // keep empty comments after child selectors (IE7 hack)
+ // e.g. html >/**/ body
+ if (token.length === 0) {
+ startIndex = css.indexOf(placeholder);
+ if (startIndex > 2) {
+ if (css.charAt(startIndex - 3) === '>') {
+ preservedTokens.push("");
+ css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___");
+ }
+ }
+ }
+
+ // in all other cases kill the comment
+ css = css.replace("/*" + placeholder + "*/", "");
+ }
+
+
+ // Normalize all whitespace strings to single spaces. Easier to work with that way.
+ css = css.replace(/\s+/g, " ");
+
+ // Remove the spaces before the things that should not have spaces before them.
+ // But, be careful not to turn "p :link {...}" into "p:link{...}"
+ // Swap out any pseudo-class colons with the token, and then swap back.
+ css = css.replace(/(^|\})(([^\{:])+:)+([^\{]*\{)/g, function (m) {
+ return m.replace(":", "___YUICSSMIN_PSEUDOCLASSCOLON___");
+ });
+ css = css.replace(/\s+([!{};:>+\(\)\],])/g, '$1');
+ css = css.replace(/___YUICSSMIN_PSEUDOCLASSCOLON___/g, ":");
+
+ // retain space for special IE6 cases
+ css = css.replace(/:first-(line|letter)(\{|,)/g, ":first-$1 $2");
+
+ // no space after the end of a preserved comment
+ css = css.replace(/\*\/ /g, '*/');
+
+
+ // If there is a @charset, then only allow one, and push to the top of the file.
+ css = css.replace(/^(.*)(@charset "[^"]*";)/gi, '$2$1');
+ css = css.replace(/^(\s*@charset [^;]+;\s*)+/gi, '$1');
+
+ // Put the space back in some cases, to support stuff like
+ // @media screen and (-webkit-min-device-pixel-ratio:0){
+ css = css.replace(/\band\(/gi, "and (");
+
+
+ // Remove the spaces after the things that should not have spaces after them.
+ css = css.replace(/([!{}:;>+\(\[,])\s+/g, '$1');
+
+ // remove unnecessary semicolons
+ css = css.replace(/;+\}/g, "}");
+
+ // Replace 0(px,em,%) with 0.
+ css = css.replace(/([\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)/gi, "$1$2");
+
+ // Replace 0 0 0 0; with 0.
+ css = css.replace(/:0 0 0 0(;|\})/g, ":0$1");
+ css = css.replace(/:0 0 0(;|\})/g, ":0$1");
+ css = css.replace(/:0 0(;|\})/g, ":0$1");
+
+ // Replace background-position:0; with background-position:0 0;
+ // same for transform-origin
+ css = css.replace(/(background-position|transform-origin|webkit-transform-origin|moz-transform-origin|o-transform-origin|ms-transform-origin):0(;|\})/gi, function(all, prop, tail) {
+ return prop.toLowerCase() + ":0 0" + tail;
+ });
+
+ // Replace 0.6 to .6, but only when preceded by : or a white-space
+ css = css.replace(/(:|\s)0+\.(\d+)/g, "$1.$2");
+
+ // Shorten colors from rgb(51,102,153) to #336699
+ // This makes it more likely that it'll get further compressed in the next step.
+ css = css.replace(/rgb\s*\(\s*([0-9,\s]+)\s*\)/gi, function () {
+ var i, rgbcolors = arguments[1].split(',');
+ for (i = 0; i < rgbcolors.length; i = i + 1) {
+ rgbcolors[i] = parseInt(rgbcolors[i], 10).toString(16);
+ if (rgbcolors[i].length === 1) {
+ rgbcolors[i] = '0' + rgbcolors[i];
+ }
+ }
+ return '#' + rgbcolors.join('');
+ });
+
+ // Shorten colors from #AABBCC to #ABC.
+ css = this._compressHexColors(css);
+
+ // border: none -> border:0
+ css = css.replace(/(border|border-top|border-right|border-bottom|border-right|outline|background):none(;|\})/gi, function(all, prop, tail) {
+ return prop.toLowerCase() + ":0" + tail;
+ });
+
+ // shorter opacity IE filter
+ css = css.replace(/progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/gi, "alpha(opacity=");
+
+ // Remove empty rules.
+ css = css.replace(/[^\};\{\/]+\{\}/g, "");
+
+ if (linebreakpos >= 0) {
+ // Some source control tools don't like it when files containing lines longer
+ // than, say 8000 characters, are checked in. The linebreak option is used in
+ // that case to split long lines after a specific column.
+ startIndex = 0;
+ i = 0;
+ while (i < css.length) {
+ i = i + 1;
+ if (css[i - 1] === '}' && i - startIndex > linebreakpos) {
+ css = css.slice(0, i) + '\n' + css.slice(i);
+ startIndex = i;
+ }
+ }
+ }
+
+ // Replace multiple semi-colons in a row by a single one
+ // See SF bug #1980989
+ css = css.replace(/;;+/g, ";");
+
+ // restore preserved comments and strings
+ for (i = 0, max = preservedTokens.length; i < max; i = i + 1) {
+ css = css.replace("___YUICSSMIN_PRESERVED_TOKEN_" + i + "___", preservedTokens[i]);
+ }
+
+ // Trim the final string (for any leading or trailing white spaces)
+ css = css.replace(/^\s+|\s+$/g, "");
+
+ return css;
+
+};
+
+exports.compressor = YAHOO.compressor;
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblessfunctionsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/functions.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/functions.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/functions.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,337 @@
</span><ins>+(function (tree) {
+
+tree.functions = {
+ rgb: function (r, g, b) {
+ return this.rgba(r, g, b, 1.0);
+ },
+ rgba: function (r, g, b, a) {
+ var rgb = [r, g, b].map(function (c) { return number(c) }),
+ a = number(a);
+ return new(tree.Color)(rgb, a);
+ },
+ hsl: function (h, s, l) {
+ return this.hsla(h, s, l, 1.0);
+ },
+ hsla: function (h, s, l, a) {
+ h = (number(h) % 360) / 360;
+ s = number(s); l = number(l); a = number(a);
+
+ var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+ var m1 = l * 2 - m2;
+
+ return this.rgba(hue(h + 1/3) * 255,
+ hue(h) * 255,
+ hue(h - 1/3) * 255,
+ a);
+
+ function hue(h) {
+ h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ else if (h * 2 < 1) return m2;
+ else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ else return m1;
+ }
+ },
+ hue: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().h));
+ },
+ saturation: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+ },
+ lightness: function (color) {
+ return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+ },
+ red: function (color) {
+ return new(tree.Dimension)(color.rgb[0]);
+ },
+ green: function (color) {
+ return new(tree.Dimension)(color.rgb[1]);
+ },
+ blue: function (color) {
+ return new(tree.Dimension)(color.rgb[2]);
+ },
+ alpha: function (color) {
+ return new(tree.Dimension)(color.toHSL().a);
+ },
+ luma: function (color) {
+ return new(tree.Dimension)(Math.round((0.2126 * (color.rgb[0]/255) +
+ 0.7152 * (color.rgb[1]/255) +
+ 0.0722 * (color.rgb[2]/255))
+ * color.alpha * 100), '%');
+ },
+ saturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s += amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ desaturate: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.s -= amount.value / 100;
+ hsl.s = clamp(hsl.s);
+ return hsla(hsl);
+ },
+ lighten: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l += amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ darken: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.l -= amount.value / 100;
+ hsl.l = clamp(hsl.l);
+ return hsla(hsl);
+ },
+ fadein: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a += amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fadeout: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a -= amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ fade: function (color, amount) {
+ var hsl = color.toHSL();
+
+ hsl.a = amount.value / 100;
+ hsl.a = clamp(hsl.a);
+ return hsla(hsl);
+ },
+ spin: function (color, amount) {
+ var hsl = color.toHSL();
+ var hue = (hsl.h + amount.value) % 360;
+
+ hsl.h = hue < 0 ? 360 + hue : hue;
+
+ return hsla(hsl);
+ },
+ //
+ // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+ // http://sass-lang.com
+ //
+ mix: function (color1, color2, weight) {
+ if (!weight) {
+ weight = new(tree.Dimension)(50);
+ }
+ var p = weight.value / 100.0;
+ var w = p * 2 - 1;
+ var a = color1.toHSL().a - color2.toHSL().a;
+
+ var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+ color1.rgb[1] * w1 + color2.rgb[1] * w2,
+ color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+ var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+ return new(tree.Color)(rgb, alpha);
+ },
+ greyscale: function (color) {
+ return this.desaturate(color, new(tree.Dimension)(100));
+ },
+ contrast: function (color, dark, light, threshold) {
+ if (typeof light === 'undefined') {
+ light = this.rgba(255, 255, 255, 1.0);
+ }
+ if (typeof dark === 'undefined') {
+ dark = this.rgba(0, 0, 0, 1.0);
+ }
+ if (typeof threshold === 'undefined') {
+ threshold = 0.43;
+ } else {
+ threshold = threshold.value;
+ }
+ if (((0.2126 * (color.rgb[0]/255) + 0.7152 * (color.rgb[1]/255) + 0.0722 * (color.rgb[2]/255)) * color.alpha) < threshold) {
+ return light;
+ } else {
+ return dark;
+ }
+ },
+ e: function (str) {
+ return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+ },
+ escape: function (str) {
+ return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+ },
+ '%': function (quoted /* arg, arg, ...*/) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ str = quoted.value;
+
+ for (var i = 0; i < args.length; i++) {
+ str = str.replace(/%[sda]/i, function(token) {
+ var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+ return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+ });
+ }
+ str = str.replace(/%%/g, '%');
+ return new(tree.Quoted)('"' + str + '"', str);
+ },
+ round: function (n, f) {
+ var fraction = typeof(f) === "undefined" ? 0 : f.value;
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(number(n).toFixed(fraction), n.unit);
+ } else if (typeof(n) === 'number') {
+ return n.toFixed(fraction);
+ } else {
+ throw { type: "Argument", message: "argument must be a number" };
+ }
+ },
+ ceil: function (n) {
+ return this._math('ceil', n);
+ },
+ floor: function (n) {
+ return this._math('floor', n);
+ },
+ _math: function (fn, n) {
+ if (n instanceof tree.Dimension) {
+ return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+ } else if (typeof(n) === 'number') {
+ return Math[fn](n);
+ } else {
+ throw { type: "Argument", message: "argument must be a number" };
+ }
+ },
+ argb: function (color) {
+ return new(tree.Anonymous)(color.toARGB());
+
+ },
+ percentage: function (n) {
+ return new(tree.Dimension)(n.value * 100, '%');
+ },
+ color: function (n) {
+ if (n instanceof tree.Quoted) {
+ return new(tree.Color)(n.value.slice(1));
+ } else {
+ throw { type: "Argument", message: "argument must be a string" };
+ }
+ },
+ iscolor: function (n) {
+ return this._isa(n, tree.Color);
+ },
+ isnumber: function (n) {
+ return this._isa(n, tree.Dimension);
+ },
+ isstring: function (n) {
+ return this._isa(n, tree.Quoted);
+ },
+ iskeyword: function (n) {
+ return this._isa(n, tree.Keyword);
+ },
+ isurl: function (n) {
+ return this._isa(n, tree.URL);
+ },
+ ispixel: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+ },
+ ispercentage: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+ },
+ isem: function (n) {
+ return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+ },
+ _isa: function (n, Type) {
+ return (n instanceof Type) ? tree.True : tree.False;
+ },
+
+ /* Blending modes */
+
+ multiply: function(color1, color2) {
+ var r = color1.rgb[0] * color2.rgb[0] / 255;
+ var g = color1.rgb[1] * color2.rgb[1] / 255;
+ var b = color1.rgb[2] * color2.rgb[2] / 255;
+ return this.rgb(r, g, b);
+ },
+ screen: function(color1, color2) {
+ var r = 255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+ var g = 255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+ var b = 255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+ return this.rgb(r, g, b);
+ },
+ overlay: function(color1, color2) {
+ var r = color1.rgb[0] < 128 ? 2 * color1.rgb[0] * color2.rgb[0] / 255 : 255 - 2 * (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+ var g = color1.rgb[1] < 128 ? 2 * color1.rgb[1] * color2.rgb[1] / 255 : 255 - 2 * (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+ var b = color1.rgb[2] < 128 ? 2 * color1.rgb[2] * color2.rgb[2] / 255 : 255 - 2 * (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+ return this.rgb(r, g, b);
+ },
+ softlight: function(color1, color2) {
+ var t = color2.rgb[0] * color1.rgb[0] / 255;
+ var r = t + color1.rgb[0] * (255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255 - t) / 255;
+ t = color2.rgb[1] * color1.rgb[1] / 255;
+ var g = t + color1.rgb[1] * (255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255 - t) / 255;
+ t = color2.rgb[2] * color1.rgb[2] / 255;
+ var b = t + color1.rgb[2] * (255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255 - t) / 255;
+ return this.rgb(r, g, b);
+ },
+ hardlight: function(color1, color2) {
+ var r = color2.rgb[0] < 128 ? 2 * color2.rgb[0] * color1.rgb[0] / 255 : 255 - 2 * (255 - color2.rgb[0]) * (255 - color1.rgb[0]) / 255;
+ var g = color2.rgb[1] < 128 ? 2 * color2.rgb[1] * color1.rgb[1] / 255 : 255 - 2 * (255 - color2.rgb[1]) * (255 - color1.rgb[1]) / 255;
+ var b = color2.rgb[2] < 128 ? 2 * color2.rgb[2] * color1.rgb[2] / 255 : 255 - 2 * (255 - color2.rgb[2]) * (255 - color1.rgb[2]) / 255;
+ return this.rgb(r, g, b);
+ },
+ difference: function(color1, color2) {
+ var r = Math.abs(color1.rgb[0] - color2.rgb[0]);
+ var g = Math.abs(color1.rgb[1] - color2.rgb[1]);
+ var b = Math.abs(color1.rgb[2] - color2.rgb[2]);
+ return this.rgb(r, g, b);
+ },
+ exclusion: function(color1, color2) {
+ var r = color1.rgb[0] + color2.rgb[0] * (255 - color1.rgb[0] - color1.rgb[0]) / 255;
+ var g = color1.rgb[1] + color2.rgb[1] * (255 - color1.rgb[1] - color1.rgb[1]) / 255;
+ var b = color1.rgb[2] + color2.rgb[2] * (255 - color1.rgb[2] - color1.rgb[2]) / 255;
+ return this.rgb(r, g, b);
+ },
+ average: function(color1, color2) {
+ var r = (color1.rgb[0] + color2.rgb[0]) / 2;
+ var g = (color1.rgb[1] + color2.rgb[1]) / 2;
+ var b = (color1.rgb[2] + color2.rgb[2]) / 2;
+ return this.rgb(r, g, b);
+ },
+ negation: function(color1, color2) {
+ var r = 255 - Math.abs(255 - color2.rgb[0] - color1.rgb[0]);
+ var g = 255 - Math.abs(255 - color2.rgb[1] - color1.rgb[1]);
+ var b = 255 - Math.abs(255 - color2.rgb[2] - color1.rgb[2]);
+ return this.rgb(r, g, b);
+ },
+ tint: function(color, amount) {
+ return this.mix(this.rgb(255,255,255), color, amount);
+ },
+ shade: function(color, amount) {
+ return this.mix(this.rgb(0, 0, 0), color, amount);
+ }
+};
+
+function hsla(hsla) {
+ return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+ if (n instanceof tree.Dimension) {
+ return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+ } else if (typeof(n) === 'number') {
+ return n;
+ } else {
+ throw {
+ error: "RuntimeError",
+ message: "color functions take numbers as parameters"
+ };
+ }
+}
+
+function clamp(val) {
+ return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblessindexjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/index.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/index.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/index.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,140 @@
</span><ins>+var path = require('path'),
+ sys = require('util'),
+ fs = require('fs');
+
+var less = {
+ version: [1, 3, 0],
+ Parser: require('./parser').Parser,
+ importer: require('./parser').importer,
+ tree: require('./tree'),
+ render: function (input, options, callback) {
+ options = options || {};
+
+ if (typeof(options) === 'function') {
+ callback = options, options = {};
+ }
+
+ var parser = new(less.Parser)(options),
+ ee;
+
+ if (callback) {
+ parser.parse(input, function (e, root) {
+ callback(e, root && root.toCSS && root.toCSS(options));
+ });
+ } else {
+ ee = new(require('events').EventEmitter);
+
+ process.nextTick(function () {
+ parser.parse(input, function (e, root) {
+ if (e) { ee.emit('error', e) }
+ else { ee.emit('success', root.toCSS(options)) }
+ });
+ });
+ return ee;
+ }
+ },
+ formatError: function(ctx, options) {
+ options = options || {};
+
+ var message = "";
+ var extract = ctx.extract;
+ var error = [];
+ var stylize = options.color ? require('./lessc_helper').stylize : function (str) { return str };
+
+ if (ctx.stack) { return stylize(ctx.stack, 'red') }
+
+ if (!ctx.hasOwnProperty('index')) {
+ return ctx.stack || ctx.message;
+ }
+
+ if (typeof(extract[0]) === 'string') {
+ error.push(stylize((ctx.line - 1) + ' ' + extract[0], 'grey'));
+ }
+
+ if (extract[1]) {
+ error.push(ctx.line + ' ' + extract[1].slice(0, ctx.column)
+ + stylize(stylize(stylize(extract[1][ctx.column], 'bold')
+ + extract[1].slice(ctx.column + 1), 'red'), 'inverse'));
+ }
+
+ if (typeof(extract[2]) === 'string') {
+ error.push(stylize((ctx.line + 1) + ' ' + extract[2], 'grey'));
+ }
+ error = error.join('\n') + stylize('', 'reset') + '\n';
+
+ message += stylize(ctx.type + 'Error: ' + ctx.message, 'red');
+ ctx.filename && (message += stylize(' in ', 'red') + ctx.filename +
+ stylize(':' + ctx.line + ':' + ctx.column, 'grey'));
+
+ message += '\n' + error;
+
+ if (ctx.callLine) {
+ message += stylize('from ', 'red') + (ctx.filename || '') + '/n';
+ message += stylize(ctx.callLine, 'grey') + ' ' + ctx.callExtract + '/n';
+ }
+
+ return message;
+ },
+ writeError: function (ctx, options) {
+ options = options || {};
+ if (options.silent) { return }
+ sys.error(less.formatError(ctx, options));
+ }
+};
+
+['color', 'directive', 'operation', 'dimension',
+ 'keyword', 'variable', 'ruleset', 'element',
+ 'selector', 'quoted', 'expression', 'rule',
+ 'call', 'url', 'alpha', 'import',
+ 'mixin', 'comment', 'anonymous', 'value',
+ 'javascript', 'assignment', 'condition', 'paren',
+ 'media', 'ratio'
+].forEach(function (n) {
+ require('./tree/' + n);
+});
+
+less.Parser.importer = function (file, paths, callback, env) {
+ var pathname;
+
+ // TODO: Undo this at some point,
+ // or use different approach.
+ var paths = [].concat(paths); // Avoid passing paths by reference down the import tree...
+ paths.unshift('.'); // ...which results on a lot of repeated '.' paths.
+
+ for (var i = 0; i < paths.length; i++) {
+ try {
+ pathname = path.join(paths[i], file);
+ fs.statSync(pathname);
+ break;
+ } catch (e) {
+ pathname = null;
+ }
+ }
+
+ if (pathname) {
+ fs.readFile(pathname, 'utf-8', function(e, data) {
+ if (e) return callback(e);
+
+ env.contents[pathname] = data; // Updating top importing parser content cache.
+ new(less.Parser)({
+ paths: [path.dirname(pathname)].concat(paths),
+ filename: pathname,
+ contents: env.contents,
+ dumpLineNumbers: env.dumpLineNumbers
+ }).parse(data, function (e, root) {
+ callback(e, root);
+ });
+ });
+ } else {
+ if (typeof(env.errback) === "function") {
+ env.errback(file, paths, callback);
+ } else {
+ callback({ type: 'File', message: "'" + file + "' wasn't found.\n" });
+ }
+ }
+}
+
+require('./functions');
+require('./colors');
+
+for (var k in less) { exports[k] = less[k] }
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesslessc_helperjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/lessc_helper.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/lessc_helper.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/lessc_helper.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+// lessc_helper.js
+//
+// helper functions for lessc
+sys = require('util');
+
+var lessc_helper = {
+
+ //Stylize a string
+ stylize : function(str, style) {
+ var styles = {
+ 'reset' : [0, 0],
+ 'bold' : [1, 22],
+ 'inverse' : [7, 27],
+ 'underline' : [4, 24],
+ 'yellow' : [33, 39],
+ 'green' : [32, 39],
+ 'red' : [31, 39],
+ 'grey' : [90, 39]
+ };
+ return '\033[' + styles[style][0] + 'm' + str +
+ '\033[' + styles[style][1] + 'm';
+ },
+
+ //Print command line options
+ printUsage: function() {
+ sys.puts("usage: lessc [options] <source> [destination]");
+ sys.puts("");
+ sys.puts("If source is set to `-' (dash or hyphen-minus), input is read from stdin.");
+ sys.puts("");
+ sys.puts("options:");
+ sys.puts(" -h, --help Print help (this message) and exit.");
+ sys.puts(" --include-path Set include paths. Separated by `:'. Use `;' on Windows.");
+ sys.puts(" --no-color Disable colorized output.");
+ sys.puts(" -s, --silent Suppress output of error messages.");
+ sys.puts(" --strict-imports Force evaluation of imports.");
+ sys.puts(" --verbose Be verbose.");
+ sys.puts(" -v, --version Print version number and exit.");
+ sys.puts(" -x, --compress Compress output by removing some whitespaces.");
+ sys.puts(" --yui-compress Compress output using cssmin.js.");
+ sys.puts(" -O0, -O1, -O2 Set the parser's optimization level. The lower");
+ sys.puts(" the number, the less nodes it will create in the");
+ sys.puts(" tree. This could matter for debugging, or if you");
+ sys.puts(" want to access the individual nodes in the tree.");
+ sys.puts(" --line-numbers=TYPE Outputs filename and line numbers.");
+ sys.puts(" TYPE can be either 'comments', which will output");
+ sys.puts(" the debug info within comments, 'mediaquery'");
+ sys.puts(" that will output the information within a fake");
+ sys.puts(" media query which is compatible with the SASS");
+ sys.puts(" format, and 'all' which will do both.");
+ sys.puts("");
+ sys.puts("Report bugs to: http://github.com/cloudhead/less.js/issues");
+ sys.puts("Home page: <http://lesscss.org/>");
+ }
+
+
+}
+
+// Exports helper functions
+for (var h in lessc_helper) { exports[h] = lessc_helper[h] }
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblessparserjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/parser.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/parser.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/parser.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,1445 @@
</span><ins>+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+ // Rhino
+ // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+ if (typeof(window) === 'undefined') { less = {} }
+ else { less = window.less = {} }
+ tree = less.tree = {};
+ less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+ // Node.js
+ less = exports,
+ tree = require('./tree');
+ less.mode = 'node';
+} else {
+ // Browser
+ if (typeof(window.less) === 'undefined') { window.less = {} }
+ less = window.less,
+ tree = window.less.tree = {};
+ less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+// A relatively straight-forward predictive parser.
+// There is no tokenization/lexing stage, the input is parsed
+// in one sweep.
+//
+// To make the parser fast enough to run in the browser, several
+// optimization had to be made:
+//
+// - Matching and slicing on a huge input is often cause of slowdowns.
+// The solution is to chunkify the input into smaller strings.
+// The chunks are stored in the `chunks` var,
+// `j` holds the current chunk index, and `current` holds
+// the index of the current chunk in relation to `input`.
+// This gives us an almost 4x speed-up.
+//
+// - In many cases, we don't need to match individual tokens;
+// for example, if a value doesn't hold any variables, operations
+// or dynamic references, the parser can effectively 'skip' it,
+// treating it as a literal.
+// An example would be '1px solid #000' - which evaluates to itself,
+// we don't need to know what the individual components are.
+// The drawback, of course is that you don't get the benefits of
+// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+// and a smaller speed-up in the code-gen.
+//
+//
+// Token matching is done with the `$` function, which either takes
+// a terminal string or regexp, or a non-terminal function to call.
+// It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+ var input, // LeSS input string
+ i, // current index in `input`
+ j, // current chunk
+ temp, // temporarily holds a chunk's state, for backtracking
+ memo, // temporarily holds `i`, when backtracking
+ furthest, // furthest index the parser has gone to
+ chunks, // chunkified input
+ current, // index of current chunk, in `input`
+ parser;
+
+ var that = this;
+
+ // Top parser on an import tree must be sure there is one "env"
+ // which will then be passed arround by reference.
+ var env = env || { };
+ if (!env.contents) { env.contents={}; } // env.contents must be passed arround with top env
+
+ // This function is called after all files
+ // have been imported through `@import`.
+ var finish = function () {};
+
+ var imports = this.imports = {
+ paths: env && env.paths || [], // Search paths, when importing
+ queue: [], // Files which haven't been imported yet
+ files: {}, // Holds the imported parse trees
+ contents: env.contents, // Holds the imported file contents
+ mime: env && env.mime, // MIME type of .less files
+ error: null, // Error in parsing/evaluating an import
+ push: function (path, callback) {
+ var that = this;
+ this.queue.push(path);
+
+ //
+ // Import a file asynchronously
+ //
+ less.Parser.importer(path, this.paths, function (e, root) {
+ that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+
+ var imported = path in that.files;
+
+ that.files[path] = root; // Store the root
+
+ if (e && !that.error) { that.error = e }
+
+ callback(e, root, imported);
+
+ if (that.queue.length === 0) { finish(e) } // Call `finish` if we're done importing
+ }, env);
+ }
+ };
+
+ function save() { temp = chunks[j], memo = i, current = i }
+ function restore() { chunks[j] = temp, i = memo, current = i }
+
+ function sync() {
+ if (i > current) {
+ chunks[j] = chunks[j].slice(i - current);
+ current = i;
+ }
+ }
+ function isWhitespace(c) {
+ // Could change to \s?
+ var code = c.charCodeAt(0);
+ return code === 32 || code === 10 || code === 9;
+ }
+ //
+ // Parse from a token, regexp or string, and move forward if match
+ //
+ function $(tok) {
+ var match, args, length, index, k;
+
+ //
+ // Non-terminal
+ //
+ if (tok instanceof Function) {
+ return tok.call(parser.parsers);
+ //
+ // Terminal
+ //
+ // Either match a single character in the input,
+ // or match a regexp in the current chunk (chunk[j]).
+ //
+ } else if (typeof(tok) === 'string') {
+ match = input.charAt(i) === tok ? tok : null;
+ length = 1;
+ sync ();
+ } else {
+ sync ();
+
+ if (match = tok.exec(chunks[j])) {
+ length = match[0].length;
+ } else {
+ return null;
+ }
+ }
+
+ // The match is confirmed, add the match length to `i`,
+ // and consume any extra white-space characters (' ' || '\n')
+ // which come after that. The reason for this is that LeSS's
+ // grammar is mostly white-space insensitive.
+ //
+ if (match) {
+ skipWhitespace(length);
+
+ if(typeof(match) === 'string') {
+ return match;
+ } else {
+ return match.length === 1 ? match[0] : match;
+ }
+ }
+ }
+
+ function skipWhitespace(length) {
+ var oldi = i, oldj = j,
+ endIndex = i + chunks[j].length,
+ mem = i += length;
+
+ while (i < endIndex) {
+ if (! isWhitespace(input.charAt(i))) { break }
+ i++;
+ }
+ chunks[j] = chunks[j].slice(length + (i - mem));
+ current = i;
+
+ if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+ return oldi !== i || oldj !== j;
+ }
+
+ function expect(arg, msg) {
+ var result = $(arg);
+ if (! result) {
+ error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+ : "unexpected token"));
+ } else {
+ return result;
+ }
+ }
+
+ function error(msg, type) {
+ throw { index: i, type: type || 'Syntax', message: msg };
+ }
+
+ // Same as $(), but don't change the state of the parser,
+ // just return the match.
+ function peek(tok) {
+ if (typeof(tok) === 'string') {
+ return input.charAt(i) === tok;
+ } else {
+ if (tok.test(chunks[j])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ function getInput(e, env) {
+ if (e.filename && env.filename && (e.filename !== env.filename)) {
+ return parser.imports.contents[e.filename];
+ } else {
+ return input;
+ }
+ }
+
+ function getLocation(index, input) {
+ for (var n = index, column = -1;
+ n >= 0 && input.charAt(n) !== '\n';
+ n--) { column++ }
+
+ return { line: typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+ column: column };
+ }
+
+ function getFileName(e) {
+ if(less.mode === 'browser' || less.mode === 'rhino')
+ return e.filename;
+ else
+ return require('path').resolve(e.filename);
+ }
+
+ function getDebugInfo(index, inputStream, e) {
+ return {
+ lineNumber: getLocation(index, inputStream).line + 1,
+ fileName: getFileName(e)
+ };
+ }
+
+ function LessError(e, env) {
+ var input = getInput(e, env),
+ loc = getLocation(e.index, input),
+ line = loc.line,
+ col = loc.column,
+ lines = input.split('\n');
+
+ this.type = e.type || 'Syntax';
+ this.message = e.message;
+ this.filename = e.filename || env.filename;
+ this.index = e.index;
+ this.line = typeof(line) === 'number' ? line + 1 : null;
+ this.callLine = e.call && (getLocation(e.call, input).line + 1);
+ this.callExtract = lines[getLocation(e.call, input).line];
+ this.stack = e.stack;
+ this.column = col;
+ this.extract = [
+ lines[line - 1],
+ lines[line],
+ lines[line + 1]
+ ];
+ }
+
+ this.env = env = env || {};
+
+ // The optimization level dictates the thoroughness of the parser,
+ // the lower the number, the less nodes it will create in the tree.
+ // This could matter for debugging, or if you want to access
+ // the individual nodes in the tree.
+ this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+ this.env.filename = this.env.filename || null;
+
+ //
+ // The Parser
+ //
+ return parser = {
+
+ imports: imports,
+ //
+ // Parse an input string into an abstract syntax tree,
+ // call `callback` when done.
+ //
+ parse: function (str, callback) {
+ var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+ i = j = current = furthest = 0;
+ input = str.replace(/\r\n/g, '\n');
+
+ // Remove potential UTF Byte Order Mark
+ input = input.replace(/^\uFEFF/, '');
+
+ // Split the input into chunks.
+ chunks = (function (chunks) {
+ var j = 0,
+ skip = /(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,
+ comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+ string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,
+ level = 0,
+ match,
+ chunk = chunks[0],
+ inParam;
+
+ for (var i = 0, c, cc; i < input.length; i++) {
+ skip.lastIndex = i;
+ if (match = skip.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ }
+ }
+ c = input.charAt(i);
+ comment.lastIndex = string.lastIndex = i;
+
+ if (match = string.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+
+ if (!inParam && c === '/') {
+ cc = input.charAt(i + 1);
+ if (cc === '/' || cc === '*') {
+ if (match = comment.exec(input)) {
+ if (match.index === i) {
+ i += match[0].length;
+ chunk.push(match[0]);
+ c = input.charAt(i);
+ }
+ }
+ }
+ }
+
+ switch (c) {
+ case '{': if (! inParam) { level ++; chunk.push(c); break }
+ case '}': if (! inParam) { level --; chunk.push(c); chunks[++j] = chunk = []; break }
+ case '(': if (! inParam) { inParam = true; chunk.push(c); break }
+ case ')': if ( inParam) { inParam = false; chunk.push(c); break }
+ default: chunk.push(c);
+ }
+ }
+ if (level > 0) {
+ error = new(LessError)({
+ index: i,
+ type: 'Parse',
+ message: "missing closing `}`",
+ filename: env.filename
+ }, env);
+ }
+
+ return chunks.map(function (c) { return c.join('') });;
+ })([[]]);
+
+ if (error) {
+ return callback(error);
+ }
+
+ // Start with the primary rule.
+ // The whole syntax tree is held under a Ruleset node,
+ // with the `root` property set to true, so no `{}` are
+ // output. The callback is called when the input is parsed.
+ try {
+ root = new(tree.Ruleset)([], $(this.parsers.primary));
+ root.root = true;
+ } catch (e) {
+ return callback(new(LessError)(e, env));
+ }
+
+ root.toCSS = (function (evaluate) {
+ var line, lines, column;
+
+ return function (options, variables) {
+ var frames = [], importError;
+
+ options = options || {};
+ //
+ // Allows setting variables with a hash, so:
+ //
+ // `{ color: new(tree.Color)('#f01') }` will become:
+ //
+ // new(tree.Rule)('@color',
+ // new(tree.Value)([
+ // new(tree.Expression)([
+ // new(tree.Color)('#f01')
+ // ])
+ // ])
+ // )
+ //
+ if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+ variables = Object.keys(variables).map(function (k) {
+ var value = variables[k];
+
+ if (! (value instanceof tree.Value)) {
+ if (! (value instanceof tree.Expression)) {
+ value = new(tree.Expression)([value]);
+ }
+ value = new(tree.Value)([value]);
+ }
+ return new(tree.Rule)('@' + k, value, false, 0);
+ });
+ frames = [new(tree.Ruleset)(null, variables)];
+ }
+
+ try {
+ var css = evaluate.call(this, { frames: frames })
+ .toCSS([], { compress: options.compress || false, dumpLineNumbers: env.dumpLineNumbers });
+ } catch (e) {
+ throw new(LessError)(e, env);
+ }
+
+ if ((importError = parser.imports.error)) { // Check if there was an error during importing
+ if (importError instanceof LessError) throw importError;
+ else throw new(LessError)(importError, env);
+ }
+
+ if (options.yuicompress && less.mode === 'node') {
+ return require('./cssmin').compressor.cssmin(css);
+ } else if (options.compress) {
+ return css.replace(/(\s)+/g, "$1");
+ } else {
+ return css;
+ }
+ };
+ })(root.eval);
+
+ // If `i` is smaller than the `input.length - 1`,
+ // it means the parser wasn't able to parse the whole
+ // string, so we've got a parsing error.
+ //
+ // We try to extract a \n delimited string,
+ // showing the line where the parse error occured.
+ // We split it up into two parts (the part which parsed,
+ // and the part which didn't), so we can color them differently.
+ if (i < input.length - 1) {
+ i = furthest;
+ lines = input.split('\n');
+ line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+ for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+ error = {
+ type: "Parse",
+ message: "Syntax Error on line " + line,
+ index: i,
+ filename: env.filename,
+ line: line,
+ column: column,
+ extract: [
+ lines[line - 2],
+ lines[line - 1],
+ lines[line]
+ ]
+ };
+ }
+
+ if (this.imports.queue.length > 0) {
+ finish = function (e) {
+ if (e) callback(e);
+ else callback(null, root);
+ };
+ } else {
+ callback(error, root);
+ }
+ },
+
+ //
+ // Here in, the parsing rules/functions
+ //
+ // The basic structure of the syntax tree generated is as follows:
+ //
+ // Ruleset -> Rule -> Value -> Expression -> Entity
+ //
+ // Here's some LESS code:
+ //
+ // .class {
+ // color: #fff;
+ // border: 1px solid #000;
+ // width: @w + 4px;
+ // > .child {...}
+ // }
+ //
+ // And here's what the parse tree might look like:
+ //
+ // Ruleset (Selector '.class', [
+ // Rule ("color", Value ([Expression [Color #fff]]))
+ // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+ // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+ // Ruleset (Selector [Element '>', '.child'], [...])
+ // ])
+ //
+ // In general, most rules will try to parse a token with the `$()` function, and if the return
+ // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+ // first, before parsing, that's when we use `peek()`.
+ //
+ parsers: {
+ //
+ // The `primary` rule is the *entry* and *exit* point of the parser.
+ // The rules here can appear at any level of the parse tree.
+ //
+ // The recursive nature of the grammar is an interplay between the `block`
+ // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+ // as represented by this simplified grammar:
+ //
+ // primary → (ruleset | rule)+
+ // ruleset → selector+ block
+ // block → '{' primary '}'
+ //
+ // Only at one point is the primary rule not called from the
+ // block rule: at the root level.
+ //
+ primary: function () {
+ var node, root = [];
+
+ while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
+ $(this.mixin.call) || $(this.comment) || $(this.directive))
+ || $(/^[\s\n]+/)) {
+ node && root.push(node);
+ }
+ return root;
+ },
+
+ // We create a Comment node for CSS comments `/* */`,
+ // but keep the LeSS comments `//` silent, by just skipping
+ // over them.
+ comment: function () {
+ var comment;
+
+ if (input.charAt(i) !== '/') return;
+
+ if (input.charAt(i + 1) === '/') {
+ return new(tree.Comment)($(/^\/\/.*/), true);
+ } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+ return new(tree.Comment)(comment);
+ }
+ },
+
+ //
+ // Entities are tokens which can be found inside an Expression
+ //
+ entities: {
+ //
+ // A string, which supports escaping " and '
+ //
+ // "milky way" 'he\'s the one!'
+ //
+ quoted: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+ e && $('~');
+
+ if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+ return new(tree.Quoted)(str[0], str[1] || str[2], e);
+ }
+ },
+
+ //
+ // A catch-all word, such as:
+ //
+ // black border-collapse
+ //
+ keyword: function () {
+ var k;
+
+ if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+ if (tree.colors.hasOwnProperty(k)) {
+ // detect named color
+ return new(tree.Color)(tree.colors[k].slice(1));
+ } else {
+ return new(tree.Keyword)(k);
+ }
+ }
+ },
+
+ //
+ // A function call
+ //
+ // rgb(255, 0, 255)
+ //
+ // We also try to catch IE's `alpha()`, but let the `alpha` parser
+ // deal with the details.
+ //
+ // The arguments are parsed with the `entities.arguments` parser.
+ //
+ call: function () {
+ var name, nameLC, args, alpha_ret, index = i;
+
+ if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+ name = name[1];
+ nameLC = name.toLowerCase();
+
+ if (nameLC === 'url') { return null }
+ else { i += name.length }
+
+ if (nameLC === 'alpha') {
+ alpha_ret = $(this.alpha);
+ if(typeof alpha_ret !== 'undefined') {
+ return alpha_ret;
+ }
+ }
+
+ $('('); // Parse the '(' and consume whitespace.
+
+ args = $(this.entities.arguments);
+
+ if (! $(')')) return;
+
+ if (name) { return new(tree.Call)(name, args, index, env.filename) }
+ },
+ arguments: function () {
+ var args = [], arg;
+
+ while (arg = $(this.entities.assignment) || $(this.expression)) {
+ args.push(arg);
+ if (! $(',')) { break }
+ }
+ return args;
+ },
+ literal: function () {
+ return $(this.entities.ratio) ||
+ $(this.entities.dimension) ||
+ $(this.entities.color) ||
+ $(this.entities.quoted);
+ },
+
+ // Assignments are argument entities for calls.
+ // They are present in ie filter properties as shown below.
+ //
+ // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+ //
+
+ assignment: function () {
+ var key, value;
+ if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+ return new(tree.Assignment)(key, value);
+ }
+ },
+
+ //
+ // Parse url() tokens
+ //
+ // We use a specific rule for urls, because they don't really behave like
+ // standard function calls. The difference is that the argument doesn't have
+ // to be enclosed within a string, so it can't be parsed as an Expression.
+ //
+ url: function () {
+ var value;
+
+ if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+ value = $(this.entities.quoted) || $(this.entities.variable) ||
+ $(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || "";
+
+ expect(')');
+
+ return new(tree.URL)((value.value != null || value instanceof tree.Variable)
+ ? value : new(tree.Anonymous)(value), imports.paths);
+ },
+
+ //
+ // A Variable entity, such as `@fink`, in
+ //
+ // width: @fink + 2px
+ //
+ // We use a different parser for variable definitions,
+ // see `parsers.variable`.
+ //
+ variable: function () {
+ var name, index = i;
+
+ if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+ return new(tree.Variable)(name, index, env.filename);
+ }
+ },
+
+ // A variable entity useing the protective {} e.g. @{var}
+ variableCurly: function () {
+ var name, curly, index = i;
+
+ if (input.charAt(i) === '@' && (curly = $(/^@\{([\w-]+)\}/))) {
+ return new(tree.Variable)("@" + curly[1], index, env.filename);
+ }
+ },
+
+ //
+ // A Hexadecimal color
+ //
+ // #4F3C2F
+ //
+ // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ //
+ color: function () {
+ var rgb;
+
+ if (input.charAt(i) === '#' && (rgb = $(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
+ return new(tree.Color)(rgb[1]);
+ }
+ },
+
+ //
+ // A Dimension, that is, a number and a unit
+ //
+ // 0.5em 95%
+ //
+ dimension: function () {
+ var value, c = input.charCodeAt(i);
+ if ((c > 57 || c < 45) || c === 47) return;
+
+ if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn|dpi|dpcm|dppx|rem|vw|vh|vmin|vm|ch)?/)) {
+ return new(tree.Dimension)(value[1], value[2]);
+ }
+ },
+
+ //
+ // A Ratio
+ //
+ // 16/9
+ //
+ ratio: function () {
+ var value, c = input.charCodeAt(i);
+ if (c > 57 || c < 48) return;
+
+ if (value = $(/^(\d+\/\d+)/)) {
+ return new(tree.Ratio)(value[1]);
+ }
+ },
+
+ //
+ // JavaScript code to be evaluated
+ //
+ // `window.location.href`
+ //
+ javascript: function () {
+ var str, j = i, e;
+
+ if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+ if (input.charAt(j) !== '`') { return }
+
+ e && $('~');
+
+ if (str = $(/^`([^`]*)`/)) {
+ return new(tree.JavaScript)(str[1], i, e);
+ }
+ }
+ },
+
+ //
+ // The variable part of a variable definition. Used in the `rule` parser
+ //
+ // @fink:
+ //
+ variable: function () {
+ var name;
+
+ if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+ },
+
+ //
+ // A font size/line-height shorthand
+ //
+ // small/12px
+ //
+ // We need to peek first, or we'll match on keywords and dimensions
+ //
+ shorthand: function () {
+ var a, b;
+
+ if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+ save();
+
+ if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+ return new(tree.Shorthand)(a, b);
+ }
+
+ restore();
+ },
+
+ //
+ // Mixins
+ //
+ mixin: {
+ //
+ // A Mixin call, with an optional argument list
+ //
+ // #mixins > .square(#fff);
+ // .rounded(4px, black);
+ // .button;
+ //
+ // The `while` loop is there because mixins can be
+ // namespaced, but we only support the child and descendant
+ // selector for now.
+ //
+ call: function () {
+ var elements = [], e, c, args = [], arg, index = i, s = input.charAt(i), name, value, important = false;
+
+ if (s !== '.' && s !== '#') { return }
+
+ save(); // stop us absorbing part of an invalid selector
+
+ while (e = $(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
+ elements.push(new(tree.Element)(c, e, i));
+ c = $('>');
+ }
+ if ($('(')) {
+ while (arg = $(this.expression)) {
+ value = arg;
+ name = null;
+
+ // Variable
+ if (arg.value.length == 1) {
+ var val = arg.value[0];
+ if (val instanceof tree.Variable) {
+ if ($(':')) {
+ if (value = $(this.expression)) {
+ name = val.name;
+ } else {
+ throw new(Error)("Expected value");
+ }
+ }
+ }
+ }
+
+ args.push({ name: name, value: value });
+
+ if (! $(',')) { break }
+ }
+ if (! $(')')) throw new(Error)("Expected )");
+ }
+
+ if ($(this.important)) {
+ important = true;
+ }
+
+ if (elements.length > 0 && ($(';') || peek('}'))) {
+ return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+ }
+
+ restore();
+ },
+
+ //
+ // A Mixin definition, with a list of parameters
+ //
+ // .rounded (@radius: 2px, @color) {
+ // ...
+ // }
+ //
+ // Until we have a finer grained state-machine, we have to
+ // do a look-ahead, to make sure we don't have a mixin call.
+ // See the `rule` function for more information.
+ //
+ // We start by matching `.rounded (`, and then proceed on to
+ // the argument list, which has optional default values.
+ // We store the parameters in `params`, with a `value` key,
+ // if there is a value, such as in the case of `@radius`.
+ //
+ // Once we've got our params list, and a closing `)`, we parse
+ // the `{...}` block.
+ //
+ definition: function () {
+ var name, params = [], match, ruleset, param, value, cond, variadic = false;
+ if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+ peek(/^[^{]*(;|})/)) return;
+
+ save();
+
+ if (match = $(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)) {
+ name = match[1];
+
+ do {
+ if (input.charAt(i) === '.' && $(/^\.{3}/)) {
+ variadic = true;
+ break;
+ } else if (param = $(this.entities.variable) || $(this.entities.literal)
+ || $(this.entities.keyword)) {
+ // Variable
+ if (param instanceof tree.Variable) {
+ if ($(':')) {
+ value = expect(this.expression, 'expected expression');
+ params.push({ name: param.name, value: value });
+ } else if ($(/^\.{3}/)) {
+ params.push({ name: param.name, variadic: true });
+ variadic = true;
+ break;
+ } else {
+ params.push({ name: param.name });
+ }
+ } else {
+ params.push({ value: param });
+ }
+ } else {
+ break;
+ }
+ } while ($(','))
+
+ // .mixincall("@{a}");
+ // looks a bit like a mixin definition.. so we have to be nice and restore
+ if (!$(')')) {
+ furthest = i;
+ restore();
+ }
+
+ if ($(/^when/)) { // Guard
+ cond = expect(this.conditions, 'expected condition');
+ }
+
+ ruleset = $(this.block);
+
+ if (ruleset) {
+ return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
+ } else {
+ restore();
+ }
+ }
+ }
+ },
+
+ //
+ // Entities are the smallest recognized token,
+ // and can be found inside a rule's value.
+ //
+ entity: function () {
+ return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+ $(this.entities.call) || $(this.entities.keyword) || $(this.entities.javascript) ||
+ $(this.comment);
+ },
+
+ //
+ // A Rule terminator. Note that we use `peek()` to check for '}',
+ // because the `block` rule will be expecting it, but we still need to make sure
+ // it's there, if ';' was ommitted.
+ //
+ end: function () {
+ return $(';') || peek('}');
+ },
+
+ //
+ // IE's alpha function
+ //
+ // alpha(opacity=88)
+ //
+ alpha: function () {
+ var value;
+
+ if (! $(/^\(opacity=/i)) return;
+ if (value = $(/^\d+/) || $(this.entities.variable)) {
+ expect(')');
+ return new(tree.Alpha)(value);
+ }
+ },
+
+ //
+ // A Selector Element
+ //
+ // div
+ // + h1
+ // #socks
+ // input[type="text"]
+ //
+ // Elements are the building blocks for Selectors,
+ // they are made out of a `Combinator` (see combinator rule),
+ // and an element name, such as a tag a class, or `*`.
+ //
+ element: function () {
+ var e, t, c, v;
+
+ c = $(this.combinator);
+
+ e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
+ $('*') || $('&') || $(this.attribute) || $(/^\([^)@]+\)/) || $(/^[\.#](?=@)/) || $(this.entities.variableCurly);
+
+ if (! e) {
+ if ($('(') && (v = ($(this.entities.variableCurly) || $(this.entities.variable))) && $(')')) {
+ e = new(tree.Paren)(v);
+ }
+ }
+
+ if (e) { return new(tree.Element)(c, e, i) }
+ },
+
+ //
+ // Combinators combine elements together, in a Selector.
+ //
+ // Because our parser isn't white-space sensitive, special care
+ // has to be taken, when parsing the descendant combinator, ` `,
+ // as it's an empty space. We have to check the previous character
+ // in the input, to see if it's a ` ` character. More info on how
+ // we deal with this in *combinator.js*.
+ //
+ combinator: function () {
+ var match, c = input.charAt(i);
+
+ if (c === '>' || c === '+' || c === '~') {
+ i++;
+ while (input.charAt(i).match(/\s/)) { i++ }
+ return new(tree.Combinator)(c);
+ } else if (input.charAt(i - 1).match(/\s/)) {
+ return new(tree.Combinator)(" ");
+ } else {
+ return new(tree.Combinator)(null);
+ }
+ },
+
+ //
+ // A CSS Selector
+ //
+ // .class > div + h1
+ // li a:hover
+ //
+ // Selectors are made out of one or more Elements, see above.
+ //
+ selector: function () {
+ var sel, e, elements = [], c, match;
+
+ // depreciated, will be removed soon
+ if ($('(')) {
+ sel = $(this.entity);
+ expect(')');
+ return new(tree.Selector)([new(tree.Element)('', sel, i)]);
+ }
+
+ while (e = $(this.element)) {
+ c = input.charAt(i);
+ elements.push(e)
+ if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+ }
+
+ if (elements.length > 0) { return new(tree.Selector)(elements) }
+ },
+ tag: function () {
+ return $(/^[A-Za-z][A-Za-z-]*[0-9]?/) || $('*');
+ },
+ attribute: function () {
+ var attr = '', key, val, op;
+
+ if (! $('[')) return;
+
+ if (key = $(/^(?:[_A-Za-z0-9-]|\\.)+/) || $(this.entities.quoted)) {
+ if ((op = $(/^[|~*$^]?=/)) &&
+ (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+ attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+ } else { attr = key }
+ }
+
+ if (! $(']')) return;
+
+ if (attr) { return "[" + attr + "]" }
+ },
+
+ //
+ // The `block` rule is used by `ruleset` and `mixin.definition`.
+ // It's a wrapper around the `primary` rule, with added `{}`.
+ //
+ block: function () {
+ var content;
+ if ($('{') && (content = $(this.primary)) && $('}')) {
+ return content;
+ }
+ },
+
+ //
+ // div, .class, body > p {...}
+ //
+ ruleset: function () {
+ var selectors = [], s, rules, match, debugInfo;
+ save();
+
+ if (env.dumpLineNumbers)
+ debugInfo = getDebugInfo(i, input, env);
+
+ while (s = $(this.selector)) {
+ selectors.push(s);
+ $(this.comment);
+ if (! $(',')) { break }
+ $(this.comment);
+ }
+
+ if (selectors.length > 0 && (rules = $(this.block))) {
+ var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports);
+ if (env.dumpLineNumbers)
+ ruleset.debugInfo = debugInfo;
+ return ruleset;
+ } else {
+ // Backtrack
+ furthest = i;
+ restore();
+ }
+ },
+ rule: function () {
+ var name, value, c = input.charAt(i), important, match;
+ save();
+
+ if (c === '.' || c === '#' || c === '&') { return }
+
+ if (name = $(this.variable) || $(this.property)) {
+ if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+ i += match[0].length - 1;
+ value = new(tree.Anonymous)(match[1]);
+ } else if (name === "font") {
+ value = $(this.font);
+ } else {
+ value = $(this.value);
+ }
+ important = $(this.important);
+
+ if (value && $(this.end)) {
+ return new(tree.Rule)(name, value, important, memo);
+ } else {
+ furthest = i;
+ restore();
+ }
+ }
+ },
+
+ //
+ // An @import directive
+ //
+ // @import "lib";
+ //
+ // Depending on our environemnt, importing is done differently:
+ // In the browser, it's an XHR request, in Node, it would be a
+ // file-system operation. The function used for importing is
+ // stored in `import`, which we pass to the Import constructor.
+ //
+ "import": function () {
+ var path, features, index = i;
+
+ save();
+
+ var dir = $(/^@import(?:-(once))?\s+/);
+
+ if (dir && (path = $(this.entities.quoted) || $(this.entities.url))) {
+ features = $(this.mediaFeatures);
+ if ($(';')) {
+ return new(tree.Import)(path, imports, features, (dir[1] === 'once'), index);
+ }
+ }
+
+ restore();
+ },
+
+ mediaFeature: function () {
+ var e, p, nodes = [];
+
+ do {
+ if (e = $(this.entities.keyword)) {
+ nodes.push(e);
+ } else if ($('(')) {
+ p = $(this.property);
+ e = $(this.entity);
+ if ($(')')) {
+ if (p && e) {
+ nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+ } else if (e) {
+ nodes.push(new(tree.Paren)(e));
+ } else {
+ return null;
+ }
+ } else { return null }
+ }
+ } while (e);
+
+ if (nodes.length > 0) {
+ return new(tree.Expression)(nodes);
+ }
+ },
+
+ mediaFeatures: function () {
+ var e, features = [];
+
+ do {
+ if (e = $(this.mediaFeature)) {
+ features.push(e);
+ if (! $(',')) { break }
+ } else if (e = $(this.entities.variable)) {
+ features.push(e);
+ if (! $(',')) { break }
+ }
+ } while (e);
+
+ return features.length > 0 ? features : null;
+ },
+
+ media: function () {
+ var features, rules, media, debugInfo;
+
+ if (env.dumpLineNumbers)
+ debugInfo = getDebugInfo(i, input, env);
+
+ if ($(/^@media/)) {
+ features = $(this.mediaFeatures);
+
+ if (rules = $(this.block)) {
+ media = new(tree.Media)(rules, features);
+ if(env.dumpLineNumbers)
+ media.debugInfo = debugInfo;
+ return media;
+ }
+ }
+ },
+
+ //
+ // A CSS Directive
+ //
+ // @charset "utf-8";
+ //
+ directive: function () {
+ var name, value, rules, identifier, e, nodes, nonVendorSpecificName,
+ hasBlock, hasIdentifier;
+
+ if (input.charAt(i) !== '@') return;
+
+ if (value = $(this['import']) || $(this.media)) {
+ return value;
+ }
+
+ save();
+
+ name = $(/^@[a-z-]+/);
+
+ nonVendorSpecificName = name;
+ if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
+ nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1);
+ }
+
+ switch(nonVendorSpecificName) {
+ case "@font-face":
+ hasBlock = true;
+ break;
+ case "@viewport":
+ case "@top-left":
+ case "@top-left-corner":
+ case "@top-center":
+ case "@top-right":
+ case "@top-right-corner":
+ case "@bottom-left":
+ case "@bottom-left-corner":
+ case "@bottom-center":
+ case "@bottom-right":
+ case "@bottom-right-corner":
+ case "@left-top":
+ case "@left-middle":
+ case "@left-bottom":
+ case "@right-top":
+ case "@right-middle":
+ case "@right-bottom":
+ hasBlock = true;
+ break;
+ case "@page":
+ case "@document":
+ case "@supports":
+ case "@keyframes":
+ hasBlock = true;
+ hasIdentifier = true;
+ break;
+ }
+
+ if (hasIdentifier) {
+ name += " " + ($(/^[^{]+/) || '').trim();
+ }
+
+ if (hasBlock)
+ {
+ if (rules = $(this.block)) {
+ return new(tree.Directive)(name, rules);
+ }
+ } else {
+ if ((value = $(this.entity)) && $(';')) {
+ return new(tree.Directive)(name, value);
+ }
+ }
+
+ restore();
+ },
+ font: function () {
+ var value = [], expression = [], weight, shorthand, font, e;
+
+ while (e = $(this.shorthand) || $(this.entity)) {
+ expression.push(e);
+ }
+ value.push(new(tree.Expression)(expression));
+
+ if ($(',')) {
+ while (e = $(this.expression)) {
+ value.push(e);
+ if (! $(',')) { break }
+ }
+ }
+ return new(tree.Value)(value);
+ },
+
+ //
+ // A Value is a comma-delimited list of Expressions
+ //
+ // font-family: Baskerville, Georgia, serif;
+ //
+ // In a Rule, a Value represents everything after the `:`,
+ // and before the `;`.
+ //
+ value: function () {
+ var e, expressions = [], important;
+
+ while (e = $(this.expression)) {
+ expressions.push(e);
+ if (! $(',')) { break }
+ }
+
+ if (expressions.length > 0) {
+ return new(tree.Value)(expressions);
+ }
+ },
+ important: function () {
+ if (input.charAt(i) === '!') {
+ return $(/^! *important/);
+ }
+ },
+ sub: function () {
+ var e;
+
+ if ($('(') && (e = $(this.expression)) && $(')')) {
+ return e;
+ }
+ },
+ multiplication: function () {
+ var m, a, op, operation;
+ if (m = $(this.operand)) {
+ while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ addition: function () {
+ var m, a, op, operation;
+ if (m = $(this.multiplication)) {
+ while ((op = $(/^[-+]\s+/) || (!isWhitespace(input.charAt(i - 1)) && ($('+') || $('-')))) &&
+ (a = $(this.multiplication))) {
+ operation = new(tree.Operation)(op, [operation || m, a]);
+ }
+ return operation || m;
+ }
+ },
+ conditions: function () {
+ var a, b, index = i, condition;
+
+ if (a = $(this.condition)) {
+ while ($(',') && (b = $(this.condition))) {
+ condition = new(tree.Condition)('or', condition || a, b, index);
+ }
+ return condition || a;
+ }
+ },
+ condition: function () {
+ var a, b, c, op, index = i, negate = false;
+
+ if ($(/^not/)) { negate = true }
+ expect('(');
+ if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+ if (op = $(/^(?:>=|=<|[<=>])/)) {
+ if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+ c = new(tree.Condition)(op, a, b, index, negate);
+ } else {
+ error('expected expression');
+ }
+ } else {
+ c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+ }
+ expect(')');
+ return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+ }
+ },
+
+ //
+ // An operand is anything that can be part of an operation,
+ // such as a Color, or a Variable
+ //
+ operand: function () {
+ var negate, p = input.charAt(i + 1);
+
+ if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+ var o = $(this.sub) || $(this.entities.dimension) ||
+ $(this.entities.color) || $(this.entities.variable) ||
+ $(this.entities.call);
+ return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+ : o;
+ },
+
+ //
+ // Expressions either represent mathematical operations,
+ // or white-space delimited Entities.
+ //
+ // 1px solid black
+ // @var * 2
+ //
+ expression: function () {
+ var e, delim, entities = [], d;
+
+ while (e = $(this.addition) || $(this.entity)) {
+ entities.push(e);
+ }
+ if (entities.length > 0) {
+ return new(tree.Expression)(entities);
+ }
+ },
+ property: function () {
+ var name;
+
+ if (name = $(/^(\*?-?[_a-z0-9-]+)\s*:/)) {
+ return name[1];
+ }
+ }
+ }
+ };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+ //
+ // Used by `@import` directives
+ //
+ less.Parser.importer = function (path, paths, callback, env) {
+ if (!/^([a-z-]+:)?\//.test(path) && paths.length > 0) {
+ path = paths[0] + path;
+ }
+ // We pass `true` as 3rd argument, to force the reload of the import.
+ // This is so we can get the syntax tree as opposed to just the CSS output,
+ // as we need this to evaluate the current stylesheet.
+ // __ Now using the hack of passing a ref to top parser's content cache in the 1st arg. __
+ loadStyleSheet({ href: path, title: path, type: env.mime, contents: env.contents }, function (e) {
+ if (e && typeof(env.errback) === "function") {
+ env.errback.call(null, path, paths, callback, env);
+ } else {
+ callback.apply(null, arguments);
+ }
+ }, true);
+ };
+}
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblessrhinojs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/rhino.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/rhino.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/rhino.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,123 @@
</span><ins>+var name;
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+ var endOfPath = Math.max(name.lastIndexOf('/'), name.lastIndexOf('\\')),
+ sheetName = name.slice(0, endOfPath + 1) + sheet.href,
+ contents = sheet.contents || {},
+ input = readFile(sheetName);
+
+ contents[sheetName] = input;
+
+ var parser = new less.Parser({
+ paths: [sheet.href.replace(/[\w\.-]+$/, '')],
+ contents: contents
+ });
+ parser.parse(input, function (e, root) {
+ if (e) {
+ return error(e, sheetName);
+ }
+ try {
+ callback(e, root, sheet, { local: false, lastModified: 0, remaining: remaining });
+ } catch(e) {
+ error(e, sheetName);
+ }
+ });
+}
+
+function writeFile(filename, content) {
+ var fstream = new java.io.FileWriter(filename);
+ var out = new java.io.BufferedWriter(fstream);
+ out.write(content);
+ out.close();
+}
+
+// Command line integration via Rhino
+(function (args) {
+ var output,
+ compress = false,
+ i;
+
+ for(i = 0; i < args.length; i++) {
+ switch(args[i]) {
+ case "-x":
+ compress = true;
+ break;
+ default:
+ if (!name) {
+ name = args[i];
+ } else if (!output) {
+ output = args[i];
+ } else {
+ print("unrecognised parameters");
+ print("input_file [output_file] [-x]");
+ }
+ }
+ }
+
+ if (!name) {
+ print('No files present in the fileset; Check your pattern match in build.xml');
+ quit(1);
+ }
+ path = name.split("/");path.pop();path=path.join("/")
+
+ var input = readFile(name);
+
+ if (!input) {
+ print('lesscss: couldn\'t open file ' + name);
+ quit(1);
+ }
+
+ var result;
+ try {
+ var parser = new less.Parser();
+ parser.parse(input, function (e, root) {
+ if (e) {
+ error(e, name);
+ quit(1);
+ } else {
+ result = root.toCSS({compress: compress || false});
+ if (output) {
+ writeFile(output, result);
+ print("Written to " + output);
+ } else {
+ print(result);
+ }
+ quit(0);
+ }
+ });
+ }
+ catch(e) {
+ error(e, name);
+ quit(1);
+ }
+ print("done");
+}(arguments));
+
+function error(e, filename) {
+
+ var content = "Error : " + filename + "\n";
+
+ filename = e.filename || filename;
+
+ if (e.message) {
+ content += e.message + "\n";
+ }
+
+ var errorline = function (e, i, classname) {
+ if (e.extract[i]) {
+ content +=
+ String(parseInt(e.line) + (i - 1)) +
+ ":" + e.extract[i] + "\n";
+ }
+ };
+
+ if (e.stack) {
+ content += e.stack;
+ } else if (e.extract) {
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n';
+ errorline(e, 0);
+ errorline(e, 1);
+ errorline(e, 2);
+ }
+ print(content);
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreealphajs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/alpha.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/alpha.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/alpha.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+(function (tree) {
+
+tree.Alpha = function (val) {
+ this.value = val;
+};
+tree.Alpha.prototype = {
+ toCSS: function () {
+ return "alpha(opacity=" +
+ (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+ },
+ eval: function (env) {
+ if (this.value.eval) { this.value = this.value.eval(env) }
+ return this;
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeanonymousjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/anonymous.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/anonymous.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/anonymous.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+(function (tree) {
+
+tree.Anonymous = function (string) {
+ this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+ toCSS: function () {
+ return this.value;
+ },
+ eval: function () { return this },
+ compare: function (x) {
+ if (!x.toCSS) {
+ return -1;
+ }
+
+ var left = this.toCSS(),
+ right = x.toCSS();
+
+ if (left === right) {
+ return 0;
+ }
+
+ return left < right ? -1 : 1;
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeassignmentjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/assignment.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/assignment.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/assignment.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+(function (tree) {
+
+tree.Assignment = function (key, val) {
+ this.key = key;
+ this.value = val;
+};
+tree.Assignment.prototype = {
+ toCSS: function () {
+ return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+ },
+ eval: function (env) {
+ if (this.value.eval) {
+ return new(tree.Assignment)(this.key, this.value.eval(env));
+ }
+ return this;
+ }
+};
+
+})(require('../tree'));
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreecalljs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/call.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/call.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/call.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+ this.name = name;
+ this.args = args;
+ this.index = index;
+ this.filename = filename;
+};
+tree.Call.prototype = {
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ eval: function (env) {
+ var args = this.args.map(function (a) { return a.eval(env) });
+
+ if (this.name in tree.functions) { // 1.
+ try {
+ return tree.functions[this.name].apply(tree.functions, args);
+ } catch (e) {
+ throw { type: e.type || "Runtime",
+ message: "error evaluating function `" + this.name + "`" +
+ (e.message ? ': ' + e.message : ''),
+ index: this.index, filename: this.filename };
+ }
+ } else { // 2.
+ return new(tree.Anonymous)(this.name +
+ "(" + args.map(function (a) { return a.toCSS(env) }).join(', ') + ")");
+ }
+ },
+
+ toCSS: function (env) {
+ return this.eval(env).toCSS();
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreecolorjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/color.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/color.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/color.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,111 @@
</span><ins>+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+ //
+ // The end goal here, is to parse the arguments
+ // into an integer triplet, such as `128, 255, 0`
+ //
+ // This facilitates operations and conversions.
+ //
+ if (Array.isArray(rgb)) {
+ this.rgb = rgb;
+ } else if (rgb.length == 6) {
+ this.rgb = rgb.match(/.{2}/g).map(function (c) {
+ return parseInt(c, 16);
+ });
+ } else {
+ this.rgb = rgb.split('').map(function (c) {
+ return parseInt(c + c, 16);
+ });
+ }
+ this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+ eval: function () { return this },
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ toCSS: function () {
+ if (this.alpha < 1.0) {
+ return "rgba(" + this.rgb.map(function (c) {
+ return Math.round(c);
+ }).concat(this.alpha).join(', ') + ")";
+ } else {
+ return '#' + this.rgb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ }
+ },
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+ operate: function (op, other) {
+ var result = [];
+
+ if (! (other instanceof tree.Color)) {
+ other = other.toColor();
+ }
+
+ for (var c = 0; c < 3; c++) {
+ result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+ }
+ return new(tree.Color)(result, this.alpha + other.alpha);
+ },
+
+ toHSL: function () {
+ var r = this.rgb[0] / 255,
+ g = this.rgb[1] / 255,
+ b = this.rgb[2] / 255,
+ a = this.alpha;
+
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h, s, l = (max + min) / 2, d = max - min;
+
+ if (max === min) {
+ h = s = 0;
+ } else {
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+ switch (max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h * 360, s: s, l: l, a: a };
+ },
+ toARGB: function () {
+ var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+ return '#' + argb.map(function (i) {
+ i = Math.round(i);
+ i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+ return i.length === 1 ? '0' + i : i;
+ }).join('');
+ },
+ compare: function (x) {
+ if (!x.rgb) {
+ return -1;
+ }
+
+ return (x.rgb[0] === this.rgb[0] &&
+ x.rgb[1] === this.rgb[1] &&
+ x.rgb[2] === this.rgb[2] &&
+ x.alpha === this.alpha) ? 0 : -1;
+ }
+};
+
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreecommentjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/comment.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/comment.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/comment.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+(function (tree) {
+
+tree.Comment = function (value, silent) {
+ this.value = value;
+ this.silent = !!silent;
+};
+tree.Comment.prototype = {
+ toCSS: function (env) {
+ return env.compress ? '' : this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeconditionjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/condition.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/condition.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/condition.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+ this.op = op.trim();
+ this.lvalue = l;
+ this.rvalue = r;
+ this.index = i;
+ this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+ var a = this.lvalue.eval(env),
+ b = this.rvalue.eval(env);
+
+ var i = this.index, result;
+
+ var result = (function (op) {
+ switch (op) {
+ case 'and':
+ return a && b;
+ case 'or':
+ return a || b;
+ default:
+ if (a.compare) {
+ result = a.compare(b);
+ } else if (b.compare) {
+ result = b.compare(a);
+ } else {
+ throw { type: "Type",
+ message: "Unable to perform comparison",
+ index: i };
+ }
+ switch (result) {
+ case -1: return op === '<' || op === '=<';
+ case 0: return op === '=' || op === '>=' || op === '=<';
+ case 1: return op === '>' || op === '>=';
+ }
+ }
+ })(this.op);
+ return this.negate ? !result : result;
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreedimensionjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/dimension.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/dimension.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/dimension.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+ this.value = parseFloat(value);
+ this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+ eval: function () { return this },
+ toColor: function () {
+ return new(tree.Color)([this.value, this.value, this.value]);
+ },
+ toCSS: function () {
+ var css = this.value + this.unit;
+ return css;
+ },
+
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
+ // In the future, we could implement some unit
+ // conversions such that `100cm + 10mm` would yield
+ // `101cm`.
+ operate: function (op, other) {
+ return new(tree.Dimension)
+ (tree.operate(op, this.value, other.value),
+ this.unit || other.unit);
+ },
+
+ // TODO: Perform unit conversion before comparing
+ compare: function (other) {
+ if (other instanceof tree.Dimension) {
+ if (other.value > this.value) {
+ return -1;
+ } else if (other.value < this.value) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ return -1;
+ }
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreedirectivejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/directive.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/directive.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/directive.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+(function (tree) {
+
+tree.Directive = function (name, value) {
+ this.name = name;
+
+ if (Array.isArray(value)) {
+ this.ruleset = new(tree.Ruleset)([], value);
+ this.ruleset.allowImports = true;
+ } else {
+ this.value = value;
+ }
+};
+tree.Directive.prototype = {
+ toCSS: function (ctx, env) {
+ if (this.ruleset) {
+ this.ruleset.root = true;
+ return this.name + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ } else {
+ return this.name + ' ' + this.value.toCSS() + ';\n';
+ }
+ },
+ eval: function (env) {
+ var evaldDirective = this;
+ if (this.ruleset) {
+ env.frames.unshift(this);
+ evaldDirective = new(tree.Directive)(this.name);
+ evaldDirective.ruleset = this.ruleset.eval(env);
+ env.frames.shift();
+ }
+ return evaldDirective;
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeelementjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/element.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/element.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/element.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+ this.combinator = combinator instanceof tree.Combinator ?
+ combinator : new(tree.Combinator)(combinator);
+
+ if (typeof(value) === 'string') {
+ this.value = value.trim();
+ } else if (value) {
+ this.value = value;
+ } else {
+ this.value = "";
+ }
+ this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+ return new(tree.Element)(this.combinator,
+ this.value.eval ? this.value.eval(env) : this.value,
+ this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+ var value = (this.value.toCSS ? this.value.toCSS(env) : this.value);
+ if (value == '' && this.combinator.value.charAt(0) == '&') {
+ return '';
+ } else {
+ return this.combinator.toCSS(env || {}) + value;
+ }
+};
+
+tree.Combinator = function (value) {
+ if (value === ' ') {
+ this.value = ' ';
+ } else {
+ this.value = value ? value.trim() : "";
+ }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+ return {
+ '' : '',
+ ' ' : ' ',
+ ':' : ' :',
+ '+' : env.compress ? '+' : ' + ',
+ '~' : env.compress ? '~' : ' ~ ',
+ '>' : env.compress ? '>' : ' > '
+ }[this.value];
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeexpressionjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/expression.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/expression.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/expression.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+ eval: function (env) {
+ if (this.value.length > 1) {
+ return new(tree.Expression)(this.value.map(function (e) {
+ return e.eval(env);
+ }));
+ } else if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return this;
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS ? e.toCSS(env) : '';
+ }).join(' ');
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeimportjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/import.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/import.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/import.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,83 @@
</span><ins>+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, once, index) {
+ var that = this;
+
+ this.once = once;
+ this.index = index;
+ this._path = path;
+ this.features = features && new(tree.Value)(features);
+
+ // The '.less' extension is optional
+ if (path instanceof tree.Quoted) {
+ this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+ } else {
+ this.path = path.value.value || path.value;
+ }
+
+ this.css = /css(\?.*)?$/.test(this.path);
+
+ // Only pre-compile .less files
+ if (! this.css) {
+ imports.push(this.path, function (e, root, imported) {
+ if (e) { e.index = index }
+ if (imported && that.once) that.skip = imported;
+ that.root = root || new(tree.Ruleset)([], []);
+ });
+ }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+ toCSS: function (env) {
+ var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+ if (this.css) {
+ return "@import " + this._path.toCSS() + features + ';\n';
+ } else {
+ return "";
+ }
+ },
+ eval: function (env) {
+ var ruleset, features = this.features && this.features.eval(env);
+
+ if (this.skip) return [];
+
+ if (this.css) {
+ return this;
+ } else {
+ ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ Array.prototype
+ .splice
+ .apply(ruleset.rules,
+ [i, 1].concat(ruleset.rules[i].eval(env)));
+ }
+ }
+ return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
+ }
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreejavascriptjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/javascript.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/javascript.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/javascript.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+ this.escaped = escaped;
+ this.expression = string;
+ this.index = index;
+};
+tree.JavaScript.prototype = {
+ eval: function (env) {
+ var result,
+ that = this,
+ context = {};
+
+ var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+ return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+ });
+
+ try {
+ expression = new(Function)('return (' + expression + ')');
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+ index: this.index };
+ }
+
+ for (var k in env.frames[0].variables()) {
+ context[k.slice(1)] = {
+ value: env.frames[0].variables()[k].value,
+ toJS: function () {
+ return this.value.eval(env).toCSS();
+ }
+ };
+ }
+
+ try {
+ result = expression.call(context);
+ } catch (e) {
+ throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+ index: this.index };
+ }
+ if (typeof(result) === 'string') {
+ return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+ } else if (Array.isArray(result)) {
+ return new(tree.Anonymous)(result.join(', '));
+ } else {
+ return new(tree.Anonymous)(result);
+ }
+ }
+};
+
+})(require('../tree'));
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreekeywordjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/keyword.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/keyword.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/keyword.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+ eval: function () { return this },
+ toCSS: function () { return this.value },
+ compare: function (other) {
+ if (other instanceof tree.Keyword) {
+ return other.value === this.value ? 0 : 1;
+ } else {
+ return -1;
+ }
+ }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreemediajs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/media.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/media.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/media.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,123 @@
</span><ins>+(function (tree) {
+
+tree.Media = function (value, features) {
+ var selectors = this.emptySelectors();
+
+ this.features = new(tree.Value)(features);
+ this.ruleset = new(tree.Ruleset)(selectors, value);
+ this.ruleset.allowImports = true;
+};
+tree.Media.prototype = {
+ toCSS: function (ctx, env) {
+ var features = this.features.toCSS(env);
+
+ this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
+ return '@media ' + features + (env.compress ? '{' : ' {\n ') +
+ this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
+ (env.compress ? '}': '\n}\n');
+ },
+ eval: function (env) {
+ if (!env.mediaBlocks) {
+ env.mediaBlocks = [];
+ env.mediaPath = [];
+ }
+
+ var blockIndex = env.mediaBlocks.length;
+ env.mediaPath.push(this);
+ env.mediaBlocks.push(this);
+
+ var media = new(tree.Media)([], []);
+ if(this.debugInfo) {
+ this.ruleset.debugInfo = this.debugInfo;
+ media.debugInfo = this.debugInfo;
+ }
+ media.features = this.features.eval(env);
+
+ env.frames.unshift(this.ruleset);
+ media.ruleset = this.ruleset.eval(env);
+ env.frames.shift();
+
+ env.mediaBlocks[blockIndex] = media;
+ env.mediaPath.pop();
+
+ return env.mediaPath.length === 0 ? media.evalTop(env) :
+ media.evalNested(env)
+ },
+ variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+ find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+ rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) },
+ emptySelectors: function() {
+ var el = new(tree.Element)('', '&', 0);
+ return [new(tree.Selector)([el])];
+ },
+
+ evalTop: function (env) {
+ var result = this;
+
+ // Render all dependent Media blocks.
+ if (env.mediaBlocks.length > 1) {
+ var selectors = this.emptySelectors();
+ result = new(tree.Ruleset)(selectors, env.mediaBlocks);
+ result.multiMedia = true;
+ }
+
+ delete env.mediaBlocks;
+ delete env.mediaPath;
+
+ return result;
+ },
+ evalNested: function (env) {
+ var i, value,
+ path = env.mediaPath.concat([this]);
+
+ // Extract the media-query conditions separated with `,` (OR).
+ for (i = 0; i < path.length; i++) {
+ value = path[i].features instanceof tree.Value ?
+ path[i].features.value : path[i].features;
+ path[i] = Array.isArray(value) ? value : [value];
+ }
+
+ // Trace all permutations to generate the resulting media-query.
+ //
+ // (a, b and c) with nested (d, e) ->
+ // a and d
+ // a and e
+ // b and c and d
+ // b and c and e
+ this.features = new(tree.Value)(this.permute(path).map(function (path) {
+ path = path.map(function (fragment) {
+ return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment);
+ });
+
+ for(i = path.length - 1; i > 0; i--) {
+ path.splice(i, 0, new(tree.Anonymous)("and"));
+ }
+
+ return new(tree.Expression)(path);
+ }));
+
+ // Fake a tree-node that doesn't output anything.
+ return new(tree.Ruleset)([], []);
+ },
+ permute: function (arr) {
+ if (arr.length === 0) {
+ return [];
+ } else if (arr.length === 1) {
+ return arr[0];
+ } else {
+ var result = [];
+ var rest = this.permute(arr.slice(1));
+ for (var i = 0; i < rest.length; i++) {
+ for (var j = 0; j < arr[0].length; j++) {
+ result.push([arr[0][j]].concat(rest[i]));
+ }
+ }
+ return result;
+ }
+ },
+ bubbleSelectors: function (selectors) {
+ this.ruleset = new(tree.Ruleset)(selectors.slice(0), [this.ruleset]);
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreemixinjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/mixin.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/mixin.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/mixin.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,146 @@
</span><ins>+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+ this.selector = new(tree.Selector)(elements);
+ this.arguments = args;
+ this.index = index;
+ this.filename = filename;
+ this.important = important;
+};
+tree.mixin.Call.prototype = {
+ eval: function (env) {
+ var mixins, args, rules = [], match = false;
+
+ for (var i = 0; i < env.frames.length; i++) {
+ if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+ args = this.arguments && this.arguments.map(function (a) {
+ return { name: a.name, value: a.value.eval(env) };
+ });
+ for (var m = 0; m < mixins.length; m++) {
+ if (mixins[m].match(args, env)) {
+ try {
+ Array.prototype.push.apply(
+ rules, mixins[m].eval(env, this.arguments, this.important).rules);
+ match = true;
+ } catch (e) {
+ throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
+ }
+ }
+ }
+ if (match) {
+ return rules;
+ } else {
+ throw { type: 'Runtime',
+ message: 'No matching definition was found for `' +
+ this.selector.toCSS().trim() + '(' +
+ this.arguments.map(function (a) {
+ return a.toCSS();
+ }).join(', ') + ")`",
+ index: this.index, filename: this.filename };
+ }
+ }
+ }
+ throw { type: 'Name',
+ message: this.selector.toCSS().trim() + " is undefined",
+ index: this.index, filename: this.filename };
+ }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition, variadic) {
+ this.name = name;
+ this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+ this.params = params;
+ this.condition = condition;
+ this.variadic = variadic;
+ this.arity = params.length;
+ this.rules = rules;
+ this._lookups = {};
+ this.required = params.reduce(function (count, p) {
+ if (!p.name || (p.name && !p.value)) { return count + 1 }
+ else { return count }
+ }, 0);
+ this.parent = tree.Ruleset.prototype;
+ this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+ toCSS: function () { return "" },
+ variable: function (name) { return this.parent.variable.call(this, name) },
+ variables: function () { return this.parent.variables.call(this) },
+ find: function () { return this.parent.find.apply(this, arguments) },
+ rulesets: function () { return this.parent.rulesets.apply(this) },
+
+ evalParams: function (env, args) {
+ var frame = new(tree.Ruleset)(null, []), varargs, arg;
+
+ for (var i = 0, val, name; i < this.params.length; i++) {
+ arg = args && args[i]
+
+ if (arg && arg.name) {
+ frame.rules.unshift(new(tree.Rule)(arg.name, arg.value.eval(env)));
+ args.splice(i, 1);
+ i--;
+ continue;
+ }
+
+ if (name = this.params[i].name) {
+ if (this.params[i].variadic && args) {
+ varargs = [];
+ for (var j = i; j < args.length; j++) {
+ varargs.push(args[j].value.eval(env));
+ }
+ frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
+ } else if (val = (arg && arg.value) || this.params[i].value) {
+ frame.rules.unshift(new(tree.Rule)(name, val.eval(env)));
+ } else {
+ throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+ ' (' + args.length + ' for ' + this.arity + ')' };
+ }
+ }
+ }
+ return frame;
+ },
+ eval: function (env, args, important) {
+ var frame = this.evalParams(env, args), context, _arguments = [], rules, start;
+
+ for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+ _arguments.push((args[i] && args[i].value) || this.params[i].value);
+ }
+ frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+ rules = important ?
+ this.rules.map(function (r) {
+ return new(tree.Rule)(r.name, r.value, '!important', r.index);
+ }) : this.rules.slice(0);
+
+ return new(tree.Ruleset)(null, rules).eval({
+ frames: [this, frame].concat(this.frames, env.frames)
+ });
+ },
+ match: function (args, env) {
+ var argsLength = (args && args.length) || 0, len, frame;
+
+ if (! this.variadic) {
+ if (argsLength < this.required) { return false }
+ if (argsLength > this.params.length) { return false }
+ if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+ }
+
+ if (this.condition && !this.condition.eval({
+ frames: [this.evalParams(env, args)].concat(env.frames)
+ })) { return false }
+
+ len = Math.min(argsLength, this.arity);
+
+ for (var i = 0; i < len; i++) {
+ if (!this.params[i].name) {
+ if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeoperationjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/operation.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/operation.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/operation.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+(function (tree) {
+
+tree.Operation = function (op, operands) {
+ this.op = op.trim();
+ this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+ var a = this.operands[0].eval(env),
+ b = this.operands[1].eval(env),
+ temp;
+
+ if (a instanceof tree.Dimension && b instanceof tree.Color) {
+ if (this.op === '*' || this.op === '+') {
+ temp = b, b = a, a = temp;
+ } else {
+ throw { name: "OperationError",
+ message: "Can't substract or divide a color from a number" };
+ }
+ }
+ return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+ switch (op) {
+ case '+': return a + b;
+ case '-': return a - b;
+ case '*': return a * b;
+ case '/': return a / b;
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeparenjs"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/paren.js</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/paren.js
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/paren.js 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/paren.js 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/paren.js
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+application/x-elc
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreequotedjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/quoted.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/quoted.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/quoted.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+ this.escaped = escaped;
+ this.value = content || '';
+ this.quote = str.charAt(0);
+ this.index = i;
+};
+tree.Quoted.prototype = {
+ toCSS: function () {
+ if (this.escaped) {
+ return this.value;
+ } else {
+ return this.quote + this.value + this.quote;
+ }
+ },
+ eval: function (env) {
+ var that = this;
+ var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+ return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+ }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+ var v = new(tree.Variable)('@' + name, that.index).eval(env);
+ return ('value' in v) ? v.value : v.toCSS();
+ });
+ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+ },
+ compare: function (x) {
+ if (!x.toCSS) {
+ return -1;
+ }
+
+ var left = this.toCSS(),
+ right = x.toCSS();
+
+ if (left === right) {
+ return 0;
+ }
+
+ return left < right ? -1 : 1;
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeratiojs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/ratio.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/ratio.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/ratio.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+(function (tree) {
+
+tree.Ratio = function (value) {
+ this.value = value;
+};
+tree.Ratio.prototype = {
+ toCSS: function (env) {
+ return this.value;
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreerulejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/rule.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/rule.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/rule.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+ this.name = name;
+ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+ this.important = important ? ' ' + important.trim() : '';
+ this.index = index;
+ this.inline = inline || false;
+
+ if (name.charAt(0) === '@') {
+ this.variable = true;
+ } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+ if (this.variable) { return "" }
+ else {
+ return this.name + (env.compress ? ':' : ': ') +
+ this.value.toCSS(env) +
+ this.important + (this.inline ? "" : ";");
+ }
+};
+
+tree.Rule.prototype.eval = function (context) {
+ return new(tree.Rule)(this.name,
+ this.value.eval(context),
+ this.important,
+ this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+ this.a = a;
+ this.b = b;
+};
+
+tree.Shorthand.prototype = {
+ toCSS: function (env) {
+ return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+ },
+ eval: function () { return this }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreerulesetjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/ruleset.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/ruleset.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/ruleset.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,374 @@
</span><ins>+(function (tree) {
+
+tree.Ruleset = function (selectors, rules, strictImports) {
+ this.selectors = selectors;
+ this.rules = rules;
+ this._lookups = {};
+ this.strictImports = strictImports;
+};
+tree.Ruleset.prototype = {
+ eval: function (env) {
+ var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+ var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports);
+ var rules = [];
+
+ ruleset.root = this.root;
+ ruleset.allowImports = this.allowImports;
+
+ if(this.debugInfo) {
+ ruleset.debugInfo = this.debugInfo;
+ }
+
+ // push the current ruleset to the frames stack
+ env.frames.unshift(ruleset);
+
+ // Evaluate imports
+ if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.Import) {
+ rules = rules.concat(ruleset.rules[i].eval(env));
+ } else {
+ rules.push(ruleset.rules[i]);
+ }
+ }
+ ruleset.rules = rules;
+ rules = [];
+ }
+
+ // Store the frames around mixin definitions,
+ // so they can be evaluated like closures when the time comes.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+ ruleset.rules[i].frames = env.frames.slice(0);
+ }
+ }
+
+ var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0;
+
+ // Evaluate mixin calls.
+ for (var i = 0; i < ruleset.rules.length; i++) {
+ if (ruleset.rules[i] instanceof tree.mixin.Call) {
+ rules = rules.concat(ruleset.rules[i].eval(env));
+ } else {
+ rules.push(ruleset.rules[i]);
+ }
+ }
+ ruleset.rules = rules;
+
+ // Evaluate everything else
+ for (var i = 0, rule; i < ruleset.rules.length; i++) {
+ rule = ruleset.rules[i];
+
+ if (! (rule instanceof tree.mixin.Definition)) {
+ ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+ }
+ }
+
+ // Pop the stack
+ env.frames.shift();
+
+ if (env.mediaBlocks) {
+ for(var i = mediaBlockCount; i < env.mediaBlocks.length; i++) {
+ env.mediaBlocks[i].bubbleSelectors(selectors);
+ }
+ }
+
+ return ruleset;
+ },
+ match: function (args) {
+ return !args || args.length === 0;
+ },
+ variables: function () {
+ if (this._variables) { return this._variables }
+ else {
+ return this._variables = this.rules.reduce(function (hash, r) {
+ if (r instanceof tree.Rule && r.variable === true) {
+ hash[r.name] = r;
+ }
+ return hash;
+ }, {});
+ }
+ },
+ variable: function (name) {
+ return this.variables()[name];
+ },
+ rulesets: function () {
+ if (this._rulesets) { return this._rulesets }
+ else {
+ return this._rulesets = this.rules.filter(function (r) {
+ return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+ });
+ }
+ },
+ find: function (selector, self) {
+ self = self || this;
+ var rules = [], rule, match,
+ key = selector.toCSS();
+
+ if (key in this._lookups) { return this._lookups[key] }
+
+ this.rulesets().forEach(function (rule) {
+ if (rule !== self) {
+ for (var j = 0; j < rule.selectors.length; j++) {
+ if (match = selector.match(rule.selectors[j])) {
+ if (selector.elements.length > rule.selectors[j].elements.length) {
+ Array.prototype.push.apply(rules, rule.find(
+ new(tree.Selector)(selector.elements.slice(1)), self));
+ } else {
+ rules.push(rule);
+ }
+ break;
+ }
+ }
+ }
+ });
+ return this._lookups[key] = rules;
+ },
+ //
+ // Entry point for code generation
+ //
+ // `context` holds an array of arrays.
+ //
+ toCSS: function (context, env) {
+ var css = [], // The CSS output
+ rules = [], // node.Rule instances
+ _rules = [], //
+ rulesets = [], // node.Ruleset instances
+ paths = [], // Current selectors
+ selector, // The fully rendered selector
+ debugInfo, // Line number debugging
+ rule;
+
+ if (! this.root) {
+ this.joinSelectors(paths, context, this.selectors);
+ }
+
+ // Compile rules and rulesets
+ for (var i = 0; i < this.rules.length; i++) {
+ rule = this.rules[i];
+
+ if (rule.rules || (rule instanceof tree.Directive) || (rule instanceof tree.Media)) {
+ rulesets.push(rule.toCSS(paths, env));
+ } else if (rule instanceof tree.Comment) {
+ if (!rule.silent) {
+ if (this.root) {
+ rulesets.push(rule.toCSS(env));
+ } else {
+ rules.push(rule.toCSS(env));
+ }
+ }
+ } else {
+ if (rule.toCSS && !rule.variable) {
+ rules.push(rule.toCSS(env));
+ } else if (rule.value && !rule.variable) {
+ rules.push(rule.value.toString());
+ }
+ }
+ }
+
+ rulesets = rulesets.join('');
+
+ // If this is the root node, we don't render
+ // a selector, or {}.
+ // Otherwise, only output if this ruleset has rules.
+ if (this.root) {
+ css.push(rules.join(env.compress ? '' : '\n'));
+ } else {
+ if (rules.length > 0) {
+ debugInfo = tree.debugInfo(env, this);
+ selector = paths.map(function (p) {
+ return p.map(function (s) {
+ return s.toCSS(env);
+ }).join('').trim();
+ }).join(env.compress ? ',' : ',\n');
+
+ // Remove duplicates
+ for (var i = rules.length - 1; i >= 0; i--) {
+ if (_rules.indexOf(rules[i]) === -1) {
+ _rules.unshift(rules[i]);
+ }
+ }
+ rules = _rules;
+
+ css.push(debugInfo + selector +
+ (env.compress ? '{' : ' {\n ') +
+ rules.join(env.compress ? '' : '\n ') +
+ (env.compress ? '}' : '\n}\n'));
+ }
+ }
+ css.push(rulesets);
+
+ return css.join('') + (env.compress ? '\n' : '');
+ },
+
+ joinSelectors: function (paths, context, selectors) {
+ for (var s = 0; s < selectors.length; s++) {
+ this.joinSelector(paths, context, selectors[s]);
+ }
+ },
+
+ joinSelector: function (paths, context, selector) {
+
+ var i, j, k,
+ hasParentSelector, newSelectors, el, sel, parentSel,
+ newSelectorPath, afterParentJoin, newJoinedSelector,
+ newJoinedSelectorEmpty, lastSelector, currentElements,
+ selectorsMultiplied;
+
+ for (i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ if (el.value === '&') {
+ hasParentSelector = true;
+ }
+ }
+
+ if (!hasParentSelector) {
+ if (context.length > 0) {
+ for(i = 0; i < context.length; i++) {
+ paths.push(context[i].concat(selector));
+ }
+ }
+ else {
+ paths.push([selector]);
+ }
+ return;
+ }
+
+ // The paths are [[Selector]]
+ // The first list is a list of comma seperated selectors
+ // The inner list is a list of inheritance seperated selectors
+ // e.g.
+ // .a, .b {
+ // .c {
+ // }
+ // }
+ // == [[.a] [.c]] [[.b] [.c]]
+ //
+
+ // the elements from the current selector so far
+ currentElements = [];
+ // the current list of new selectors to add to the path.
+ // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
+ // by the parents
+ newSelectors = [[]];
+
+ for (i = 0; i < selector.elements.length; i++) {
+ el = selector.elements[i];
+ // non parent reference elements just get added
+ if (el.value !== "&") {
+ currentElements.push(el);
+ } else {
+ // the new list of selectors to add
+ selectorsMultiplied = [];
+
+ // merge the current list of non parent selector elements
+ // on to the current list of selectors to add
+ if (currentElements.length > 0) {
+ this.mergeElementsOnToSelectors(currentElements, newSelectors);
+ }
+
+ // loop through our current selectors
+ for(j = 0; j < newSelectors.length; j++) {
+ sel = newSelectors[j];
+ // if we don't have any parent paths, the & might be in a mixin so that it can be used
+ // whether there are parents or not
+ if (context.length == 0) {
+ // the combinator used on el should now be applied to the next element instead so that
+ // it is not lost
+ if (sel.length > 0) {
+ sel[0].elements = sel[0].elements.slice(0);
+ sel[0].elements.push(new(tree.Element)(el.combinator, '', 0)); //new Element(el.Combinator, ""));
+ }
+ selectorsMultiplied.push(sel);
+ }
+ else {
+ // and the parent selectors
+ for(k = 0; k < context.length; k++) {
+ parentSel = context[k];
+ // We need to put the current selectors
+ // then join the last selector's elements on to the parents selectors
+
+ // our new selector path
+ newSelectorPath = [];
+ // selectors from the parent after the join
+ afterParentJoin = [];
+ newJoinedSelectorEmpty = true;
+
+ //construct the joined selector - if & is the first thing this will be empty,
+ // if not newJoinedSelector will be the last set of elements in the selector
+ if (sel.length > 0) {
+ newSelectorPath = sel.slice(0);
+ lastSelector = newSelectorPath.pop();
+ newJoinedSelector = new(tree.Selector)(lastSelector.elements.slice(0));
+ newJoinedSelectorEmpty = false;
+ }
+ else {
+ newJoinedSelector = new(tree.Selector)([]);
+ }
+
+ //put together the parent selectors after the join
+ if (parentSel.length > 1) {
+ afterParentJoin = afterParentJoin.concat(parentSel.slice(1));
+ }
+
+ if (parentSel.length > 0) {
+ newJoinedSelectorEmpty = false;
+
+ // join the elements so far with the first part of the parent
+ newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, 0));
+ newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1));
+ }
+
+ if (!newJoinedSelectorEmpty) {
+ // now add the joined selector
+ newSelectorPath.push(newJoinedSelector);
+ }
+
+ // and the rest of the parent
+ newSelectorPath = newSelectorPath.concat(afterParentJoin);
+
+ // add that to our new set of selectors
+ selectorsMultiplied.push(newSelectorPath);
+ }
+ }
+ }
+
+ // our new selectors has been multiplied, so reset the state
+ newSelectors = selectorsMultiplied;
+ currentElements = [];
+ }
+ }
+
+ // if we have any elements left over (e.g. .a& .b == .b)
+ // add them on to all the current selectors
+ if (currentElements.length > 0) {
+ this.mergeElementsOnToSelectors(currentElements, newSelectors);
+ }
+
+ for(i = 0; i < newSelectors.length; i++) {
+ paths.push(newSelectors[i]);
+ }
+ },
+
+ mergeElementsOnToSelectors: function(elements, selectors) {
+ var i, sel;
+
+ if (selectors.length == 0) {
+ selectors.push([ new(tree.Selector)(elements) ]);
+ return;
+ }
+
+ for(i = 0; i < selectors.length; i++) {
+ sel = selectors[i];
+
+ // if the previous thing in sel is a parent this needs to join on to it
+ if (sel.length > 0) {
+ sel[sel.length - 1] = new(tree.Selector)(sel[sel.length - 1].elements.concat(elements));
+ }
+ else {
+ sel.push(new(tree.Selector)(elements));
+ }
+ }
+ }
+};
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeselectorjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/selector.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/selector.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/selector.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,47 @@
</span><ins>+(function (tree) {
+
+tree.Selector = function (elements) {
+ this.elements = elements;
+};
+tree.Selector.prototype.match = function (other) {
+ var len = this.elements.length,
+ olen = other.elements.length,
+ max = Math.min(len, olen);
+
+ if (len < olen) {
+ return false;
+ } else {
+ for (var i = 0; i < max; i++) {
+ if (this.elements[i].value !== other.elements[i].value) {
+ return false;
+ }
+ }
+ }
+ return true;
+};
+tree.Selector.prototype.eval = function (env) {
+ return new(tree.Selector)(this.elements.map(function (e) {
+ return e.eval(env);
+ }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+ if (this._css) { return this._css }
+
+ if (this.elements[0].combinator.value === "") {
+ this._css = ' ';
+ } else {
+ this._css = '';
+ }
+
+ this._css += this.elements.map(function (e) {
+ if (typeof(e) === 'string') {
+ return ' ' + e.trim();
+ } else {
+ return e.toCSS(env);
+ }
+ }).join('');
+
+ return this._css;
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreeurljs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/url.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/url.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/url.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+(function (tree) {
+
+tree.URL = function (val, paths) {
+ this.value = val;
+ this.paths = paths;
+};
+tree.URL.prototype = {
+ toCSS: function () {
+ return "url(" + this.value.toCSS() + ")";
+ },
+ eval: function (ctx) {
+ var val = this.value.eval(ctx);
+
+ // Add the base path if the URL is relative and we are either
+ // a.) in the browser or
+ // b.) we have a relative file URL
+ if ((this.paths.length > 0) &&
+ (typeof window !== 'undefined' || !/^(?:[A-Za-z-]+:|\/)/.test(this.paths[0])) &&
+ (typeof val.value === "string" && !/^(?:[a-z-]+:|\/)/.test(val.value))) {
+ var path = this.paths[0].slice(-1) === '/' ? this.paths[0] : this.paths[0] + '/';
+ var v = path + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+ val = new(tree.Anonymous)(v);
+ }
+
+ return new(tree.URL)(val, this.paths);
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreevaluejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/value.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/value.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/value.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+(function (tree) {
+
+tree.Value = function (value) {
+ this.value = value;
+ this.is = 'value';
+};
+tree.Value.prototype = {
+ eval: function (env) {
+ if (this.value.length === 1) {
+ return this.value[0].eval(env);
+ } else {
+ return new(tree.Value)(this.value.map(function (v) {
+ return v.eval(env);
+ }));
+ }
+ },
+ toCSS: function (env) {
+ return this.value.map(function (e) {
+ return e.toCSS(env);
+ }).join(env.compress ? ',' : ', ');
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreevariablejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/variable.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/variable.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree/variable.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+ eval: function (env) {
+ var variable, v, name = this.name;
+
+ if (name.indexOf('@@') == 0) {
+ name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+ }
+
+ if (variable = tree.find(env.frames, function (frame) {
+ if (v = frame.variable(name)) {
+ return v.value.eval(env);
+ }
+ })) { return variable }
+ else {
+ throw { type: 'Name',
+ message: "variable " + name + " is undefined",
+ filename: this.file,
+ index: this.index };
+ }
+ }
+};
+
+})(require('../tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslessliblesstreejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/lib/less/tree.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+(function (tree) {
+
+tree.debugInfo = function(env, ctx) {
+ var result="";
+ if (env.dumpLineNumbers && !env.compress) {
+ switch(env.dumpLineNumbers) {
+ case 'comments':
+ result = tree.debugInfo.asComment(ctx);
+ break;
+ case 'mediaquery':
+ result = tree.debugInfo.asMediaQuery(ctx);
+ break;
+ case 'all':
+ result = tree.debugInfo.asComment(ctx)+tree.debugInfo.asMediaQuery(ctx);
+ break;
+ }
+ }
+ return result;
+};
+
+tree.debugInfo.asComment = function(ctx) {
+ return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n';
+};
+
+tree.debugInfo.asMediaQuery = function(ctx) {
+ return '@media -sass-debug-info{filename{font-family:"' + ctx.debugInfo.fileName + '";}line{font-family:"' + ctx.debugInfo.lineNumber + '";}}\n';
+};
+
+tree.find = function (obj, fun) {
+ for (var i = 0, r; i < obj.length; i++) {
+ if (r = fun.call(obj, obj[i])) { return r }
+ }
+ return null;
+};
+tree.jsify = function (obj) {
+ if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+ } else {
+ return obj.toCSS(false);
+ }
+};
+
+})(require('./tree'));
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesspackagejson"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/package.json (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/package.json (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/package.json 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+{
+ "name" : "less",
+ "description" : "Leaner CSS",
+ "url" : "http://lesscss.org",
+ "keywords" : ["css", "parser", "lesscss", "browser"],
+ "author" : "Alexis Sellier <self@cloudhead.net>",
+ "contributors" : [],
+ "version" : "1.3.0",
+ "bin" : { "lessc": "./bin/lessc" },
+ "main" : "./lib/less/index",
+ "directories" : { "test": "./test" },
+ "engines" : { "node": ">=0.4.0" },
+ "devDependencies" : { "diff": "~1.0.2" },
+ "scripts": {
+ "test": "make test"
+ }
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsscolorscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/colors.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/colors.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/colors.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,77 @@
</span><ins>+#yelow #short {
+ color: #fea;
+}
+#yelow #long {
+ color: #ffeeaa;
+}
+#yelow #rgba {
+ color: rgba(255, 238, 170, 0.1);
+}
+#yelow #argb {
+ color: #1affeeaa;
+}
+#blue #short {
+ color: #00f;
+}
+#blue #long {
+ color: #0000ff;
+}
+#blue #rgba {
+ color: rgba(0, 0, 255, 0.1);
+}
+#blue #argb {
+ color: #1a0000ff;
+}
+#alpha #hsla {
+ color: rgba(61, 45, 41, 0.6);
+}
+#overflow .a {
+ color: #000000;
+}
+#overflow .b {
+ color: #ffffff;
+}
+#overflow .c {
+ color: #ffffff;
+}
+#overflow .d {
+ color: #00ff00;
+}
+#grey {
+ color: #c8c8c8;
+}
+#808080 {
+ color: #808080;
+}
+#00ff00 {
+ color: #00ff00;
+}
+.lightenblue {
+ color: #3333ff;
+}
+.darkenblue {
+ color: #0000cc;
+}
+.unknowncolors {
+ color: blue2;
+ border: 2px solid superred;
+}
+.transparent {
+ color: transparent;
+ background-color: rgba(0, 0, 0, 0);
+}
+#alpha #fromvar {
+ opacity: 0.7;
+}
+#alpha #short {
+ opacity: 1;
+}
+#alpha #long {
+ opacity: 1;
+}
+#alpha #rgba {
+ opacity: 0.2;
+}
+#alpha #hsl {
+ opacity: 1;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsscommentscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/comments.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/comments.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/comments.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+/******************\
+* *
+* Comment Header *
+* *
+\******************/
+/*
+
+ Comment
+
+*/
+/*
+ * Comment Test
+ *
+ * - cloudhead (http://cloudhead.net)
+ *
+ */
+/* Colors
+ * ------
+ * #EDF8FC (background blue)
+ * #166C89 (darkest blue)
+ *
+ * Text:
+ * #333 (standard text) // A comment within a comment!
+ * #1F9EC9 (standard link)
+ *
+ */
+/* @group Variables
+------------------- */
+#comments {
+ /**/
+ color: red;
+ /* A C-style comment */
+
+ background-color: orange;
+ font-size: 12px;
+ /* lost comment */
+ content: "content";
+ border: 1px solid black;
+ padding: 0;
+ margin: 2em;
+}
+/* commented out
+ #more-comments {
+ color: grey;
+ }
+*/
+.selector,
+.lots,
+.comments {
+ color: #808080, /* blue */ #ffa500;
+ -webkit-border-radius: 2px /* webkit only */;
+ -moz-border-radius: 8px /* moz only with operation */;
+}
+#last {
+ color: #0000ff;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsscss3css"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/css-3.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/css-3.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/css-3.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+.comma-delimited {
+ background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+ text-shadow: -1px -1px 1px #ff0000, 6px 5px 5px #ffff00;
+ -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
+}
+@font-face {
+ font-family: Headline;
+ src: local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg");
+}
+.other {
+ -moz-transform: translate(0, 11em) rotate(-90deg);
+ transform: rotateX(45deg);
+}
+.item[data-cra_zy-attr1b-ut3=bold] {
+ font-weight: bold;
+}
+p:not([class*="lead"]) {
+ color: black;
+}
+input[type="text"].class#id[attr=32]:not(1) {
+ color: white;
+}
+div#id.class[a=1][b=2].class:not(1) {
+ color: white;
+}
+ul.comma > li:not(:only-child)::after {
+ color: white;
+}
+ol.comma > li:nth-last-child(2)::after {
+ color: white;
+}
+li:nth-child(4n+1),
+li:nth-child(-5n),
+li:nth-child(-n+2) {
+ color: white;
+}
+a[href^="http://"] {
+ color: black;
+}
+a[href$="http://"] {
+ color: black;
+}
+form[data-disabled] {
+ color: black;
+}
+p::before {
+ color: black;
+}
+#issue322 {
+ -webkit-animation: anim2 7s infinite ease-in-out;
+}
+@-webkit-keyframes frames {
+ 0% {
+ border: 1px;
+ }
+ 5.5% {
+ border: 2px;
+ }
+ 100% {
+ border: 3px;
+ }
+}
+@keyframes fontbulger1 {
+ to {
+ font-size: 15px;
+ }
+ from,
+ to {
+ font-size: 12px;
+ }
+ 0%,
+ 100% {
+ font-size: 12px;
+ }
+}
+.units {
+ font: 1.2rem/2rem;
+ font: 8vw/9vw;
+ font: 10vh/12vh;
+ font: 12vm/15vm;
+ font: 12vmin/15vmin;
+ font: 1.2ch/1.5ch;
+}
+@supports ( box-shadow: 2px 2px 2px black ) or
+ ( -moz-box-shadow: 2px 2px 2px black ) {
+ .outline {
+ box-shadow: 2px 2px 2px black;
+ -moz-box-shadow: 2px 2px 2px black;
+ }
+}
+@-x-document url-prefix(""github.com"") {
+ h1 {
+ color: red;
+ }
+}
+@viewport {
+ font-size: 10px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsscssescapescss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/css-escapes.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/css-escapes.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/css-escapes.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+.escape\|random\|char {
+ color: red;
+}
+.mixin\!tUp {
+ font-weight: bold;
+}
+.\34 04 {
+ background: red;
+}
+.\34 04 strong {
+ color: #ff00ff;
+ font-weight: bold;
+}
+.trailingTest\+ {
+ color: red;
+}
+/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */
+\62\6c\6f \63 \6B \0071 \000075o\74 e {
+ color: silver;
+}
+[ng\:cloak],
+ng\:form {
+ display: none;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsscsscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/css.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/css.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/css.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,100 @@
</span><ins>+@charset "utf-8";
+div {
+ color: black;
+}
+div {
+ width: 99%;
+}
+* {
+ min-width: 45em;
+}
+h1,
+h2 > a > p,
+h3 {
+ color: none;
+}
+div.class {
+ color: blue;
+}
+div#id {
+ color: green;
+}
+.class#id {
+ color: purple;
+}
+.one.two.three {
+ color: grey;
+}
+@media print {
+ font-size: 3em;
+}
+@media screen {
+ font-size: 10px;
+}
+@font-face {
+ font-family: 'Garamond Pro';
+ src: url("/fonts/garamond-pro.ttf");
+}
+a:hover,
+a:link {
+ color: #999;
+}
+p,
+p:first-child {
+ text-transform: none;
+}
+q:lang(no) {
+ quotes: none;
+}
+p + h1 {
+ font-size: 2.2em;
+}
+#shorthands {
+ border: 1px solid #000;
+ font: 12px/16px Arial;
+ font: 100%/16px Arial;
+ margin: 1px 0;
+ padding: 0 auto;
+ background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#more-shorthands {
+ margin: 0;
+ padding: 1px 0 2px 0;
+ font: normal small/20px 'Trebuchet MS', Verdana, sans-serif;
+ font: 0/0 a;
+}
+.misc {
+ -moz-border-radius: 2px;
+ display: -moz-inline-stack;
+ width: .1em;
+ background-color: #009998;
+ background-image: url(images/image.jpg);
+ background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), to(#0000ff));
+ margin: ;
+ filter: alpha(opacity=100);
+}
+#important {
+ color: red !important;
+ width: 100%!important;
+ height: 20px ! important;
+}
+#data-uri {
+ background: url(data:image/png;charset=utf-8;base64,
+ kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+ k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+ kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+ background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+ background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+#svg-data-uri {
+ background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+@font-face {
+ font-family: font-a;
+}
+@font-face {
+ font-family: font-b;
+}
+.æøå {
+ margin: 0;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssdebuglinenumbersallcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/linenumbers-all.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/linenumbers-all.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/linenumbers-all.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+/* line 21, {pathimport}test.less */
+@media -sass-debug-info{filename{font-family:"{pathimport}test.less";}line{font-family:"21";}}
+.tst3 {
+ color: grey;
+}
+/* line 13, {path}linenumbers.less */
+@media -sass-debug-info{filename{font-family:"{path}linenumbers.less";}line{font-family:"13";}}
+.test1 {
+ color: black;
+}
+/* line 4, {path}linenumbers.less */
+@media -sass-debug-info{filename{font-family:"{path}linenumbers.less";}line{font-family:"4";}}
+.test2 {
+ color: red;
+}
+@media all {
+ /* line 3, {pathimport}test.less */
+ @media -sass-debug-info{filename{font-family:"{pathimport}test.less";}line{font-family:"3";}}
+ .tst {
+ color: black;
+ }
+}
+@media all and screen {
+ /* line 5, {pathimport}test.less */
+ @media -sass-debug-info{filename{font-family:"{pathimport}test.less";}line{font-family:"5";}}
+ .tst {
+ color: red;
+ }
+ /* line 7, {pathimport}test.less */
+ @media -sass-debug-info{filename{font-family:"{pathimport}test.less";}line{font-family:"7";}}
+ .tst .tst3 {
+ color: white;
+ }
+}
+/* line 16, {pathimport}test.less */
+@media -sass-debug-info{filename{font-family:"{pathimport}test.less";}line{font-family:"16";}}
+.tst2 {
+ color: white;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssdebuglinenumberscommentscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/linenumbers-comments.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/linenumbers-comments.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/linenumbers-comments.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+/* line 21, {pathimport}test.less */
+.tst3 {
+ color: grey;
+}
+/* line 13, {path}linenumbers.less */
+.test1 {
+ color: black;
+}
+/* line 4, {path}linenumbers.less */
+.test2 {
+ color: red;
+}
+@media all {
+ /* line 3, {pathimport}test.less */
+ .tst {
+ color: black;
+ }
+}
+@media all and screen {
+ /* line 5, {pathimport}test.less */
+ .tst {
+ color: red;
+ }
+ /* line 7, {pathimport}test.less */
+ .tst .tst3 {
+ color: white;
+ }
+}
+/* line 16, {pathimport}test.less */
+.tst2 {
+ color: white;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssdebuglinenumbersmediaquerycss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/linenumbers-mediaquery.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/linenumbers-mediaquery.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/debug/linenumbers-mediaquery.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+@media -sass-debug-info{filename{font-family:"{pathimport}test.less";}line{font-family:"21";}}
+.tst3 {
+ color: grey;
+}
+@media -sass-debug-info{filename{font-family:"{path}linenumbers.less";}line{font-family:"13";}}
+.test1 {
+ color: black;
+}
+@media -sass-debug-info{filename{font-family:"{path}linenumbers.less";}line{font-family:"4";}}
+.test2 {
+ color: red;
+}
+@media all {
+ @media -sass-debug-info{filename{font-family:"{pathimport}test.less";}line{font-family:"3";}}
+ .tst {
+ color: black;
+ }
+}
+@media all and screen {
+ @media -sass-debug-info{filename{font-family:"{pathimport}test.less";}line{font-family:"5";}}
+ .tst {
+ color: red;
+ }
+ @media -sass-debug-info{filename{font-family:"{pathimport}test.less";}line{font-family:"7";}}
+ .tst .tst3 {
+ color: white;
+ }
+}
+@media -sass-debug-info{filename{font-family:"{pathimport}test.less";}line{font-family:"16";}}
+.tst2 {
+ color: white;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssfunctionscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/functions.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/functions.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/functions.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,92 @@
</span><ins>+#functions {
+ color: #660000;
+ width: 16;
+ height: undefined("self");
+ border-width: 5;
+ variable: 11;
+ background: linear-gradient(#000000, #ffffff);
+}
+#built-in {
+ escaped: -Some::weird(#thing, y);
+ lighten: #ffcccc;
+ darken: #330000;
+ saturate: #203c31;
+ desaturate: #29332f;
+ greyscale: #2e2e2e;
+ spin-p: #bf6a40;
+ spin-n: #bf4055;
+ luma-white: 100%;
+ luma-black: 0%;
+ luma-black-alpha: 0%;
+ luma-red: 21%;
+ luma-green: 72%;
+ luma-blue: 7%;
+ luma-yellow: 93%;
+ luma-cyan: 79%;
+ luma-white-alpha: 50%;
+ contrast-white: #000000;
+ contrast-black: #ffffff;
+ contrast-red: #ffffff;
+ contrast-green: #000000;
+ contrast-blue: #ffffff;
+ contrast-yellow: #000000;
+ contrast-cyan: #000000;
+ contrast-light: #111111;
+ contrast-dark: #eeeeee;
+ contrast-light-thresh: #111111;
+ contrast-dark-thresh: #eeeeee;
+ contrast-high-thresh: #eeeeee;
+ contrast-low-thresh: #111111;
+ format: "rgb(32, 128, 64)";
+ format-string: "hello world";
+ format-multiple: "hello earth 2";
+ format-url-encode: "red is %23ff0000";
+ eformat: rgb(32, 128, 64);
+ hue: 98;
+ saturation: 12%;
+ lightness: 95%;
+ red: 255;
+ green: 255;
+ blue: 255;
+ rounded: 11;
+ rounded-two: 10.67;
+ roundedpx: 3px;
+ roundedpx-three: 3.333px;
+ percentage: 20%;
+ color: #ff0011;
+ tint: #898989;
+ tint-full: #ffffff;
+ tint-percent: #898989;
+ shade: #686868;
+ shade-full: #000000;
+ shade-percent: #686868;
+ mix: #ff3300;
+ mix-0: #ffff00;
+ mix-100: #ff0000;
+ mix-weightless: #ff8000;
+}
+#built-in .is-a {
+ color: true;
+ color1: true;
+ color2: true;
+ keyword: true;
+ number: true;
+ string: true;
+ pixel: true;
+ percent: true;
+ em: true;
+}
+#alpha {
+ alpha: rgba(153, 94, 51, 0.6);
+}
+#blendmodes {
+ multiply: #ed0000;
+ screen: #f600f6;
+ overlay: #ed0000;
+ softlight: #ff0000;
+ hardlight: #0000ed;
+ difference: #f600f6;
+ exclusion: #f600f6;
+ average: #7b007b;
+ negation: #d73131;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssiefilterscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/ie-filters.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/ie-filters.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/ie-filters.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+.nav {
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity=20);
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="#000000", GradientType=0);
+}
+.evalTest1 {
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity=30);
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity=5);
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssimportoncecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/import-once.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/import-once.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/import-once.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+@import "import-test-d.css";
+
+@import "../import-test-d.css";
+#import {
+ color: #ff0000;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssimportcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/import.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/import.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/import.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+@import "import-test-d.css";
+
+@import url(http://fonts.googleapis.com/css?family=Open+Sans);
+
+@import url(something.css) screen and (color) and (max-width: 600px);
+#import {
+ color: #ff0000;
+}
+.mixin {
+ height: 10px;
+ color: #ff0000;
+}
+#import-test {
+ height: 10px;
+ color: #ff0000;
+ width: 10px;
+ height: 30%;
+}
+@media screen and (max-width: 600px) {
+ body {
+ width: 100%;
+ }
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssjavascriptcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/javascript.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/javascript.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/javascript.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+.eval {
+ js: 42;
+ js: 2;
+ js: "hello world";
+ js: 1, 2, 3;
+ title: "string";
+ ternary: true;
+ multiline: 2;
+}
+.scope {
+ var: 42;
+ escaped: 7px;
+}
+.vars {
+ width: 8;
+}
+.escape-interpol {
+ width: hello world;
+}
+.arrays {
+ ary: "1, 2, 3";
+ ary1: "1, 2, 3";
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsslazyevalcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/lazy-eval.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/lazy-eval.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/lazy-eval.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+.lazy-eval {
+ width: 100%;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmediacss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/media.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/media.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/media.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,176 @@
</span><ins>+@media print {
+ .class {
+ color: blue;
+ }
+ .class .sub {
+ width: 42;
+ }
+ .top,
+ header > h1 {
+ color: #444444;
+ }
+}
+@media screen {
+ body {
+ max-width: 480;
+ }
+}
+@media all and (device-aspect-ratio: 16/9) {
+ body {
+ max-width: 800px;
+ }
+}
+@media all and (orientation: portrait) {
+ aside {
+ float: none;
+ }
+}
+@media handheld and (min-width: 42), screen and (min-width: 20em) {
+ body {
+ max-width: 480px;
+ }
+}
+@media print {
+ body {
+ padding: 20px;
+ }
+ body header {
+ background-color: red;
+ }
+}
+@media print and (orientation: landscape) {
+ body {
+ margin-left: 20px;
+ }
+}
+@media screen {
+ .sidebar {
+ width: 300px;
+ }
+}
+@media screen and (orientation: landscape) {
+ .sidebar {
+ width: 500px;
+ }
+}
+@media a {
+
+}
+@media a and b {
+ .first .second .third {
+ width: 300px;
+ }
+ .first .second .fourth {
+ width: 3;
+ }
+}
+@media a and b and c {
+ .first .second .third {
+ width: 500px;
+ }
+}
+@media a, b and c {
+ body {
+ width: 95%;
+ }
+}
+@media a and x, b and c and x, a and y, b and c and y {
+ body {
+ width: 100%;
+ }
+}
+.a {
+ background: black;
+}
+@media handheld {
+ .a {
+ background: white;
+ }
+}
+@media handheld and (max-width: 100px) {
+ .a {
+ background: red;
+ }
+}
+.b {
+ background: black;
+}
+@media handheld {
+ .b {
+ background: white;
+ }
+}
+@media handheld and (max-width: 200px) {
+ .b {
+ background: red;
+ }
+}
+@media only screen and (max-width: 200px) {
+ width: 480px;
+}
+@media print {
+ @page :left {
+ margin: 0.5cm;
+ }
+ @page :right {
+ margin: 0.5cm;
+ }
+ @page Test:first {
+ margin: 1cm;
+ }
+ @page :first {
+ size: 8.5in 11in;@top-left {
+ margin: 1cm;
+ }
+ @top-left-corner {
+ margin: 1cm;
+ }
+ @top-center {
+ margin: 1cm;
+ }
+ @top-right {
+ margin: 1cm;
+ }
+ @top-right-corner {
+ margin: 1cm;
+ }
+ @bottom-left {
+ margin: 1cm;
+ }
+ @bottom-left-corner {
+ margin: 1cm;
+ }
+ @bottom-center {
+ margin: 1cm;
+ }
+ @bottom-right {
+ margin: 1cm;
+ }
+ @bottom-right-corner {
+ margin: 1cm;
+ }
+ @left-top {
+ margin: 1cm;
+ }
+ @left-middle {
+ margin: 1cm;
+ }
+ @left-bottom {
+ margin: 1cm;
+ }
+ @right-top {
+ margin: 1cm;
+ }
+ @right-middle {
+ content: "Page " counter(page);
+ }
+ @right-bottom {
+ margin: 1cm;
+ }
+ }
+}
+@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 128dpcm) {
+ .b {
+ background: red;
+ }
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinsargscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-args.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-args.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-args.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+#hidden {
+ color: transparent;
+}
+#hidden1 {
+ color: transparent;
+}
+.two-args {
+ color: blue;
+ width: 10px;
+ height: 99%;
+ border: 2px dotted #000000;
+}
+.one-arg {
+ width: 15px;
+ height: 49%;
+}
+.no-parens {
+ width: 5px;
+ height: 49%;
+}
+.no-args {
+ width: 5px;
+ height: 49%;
+}
+.var-args {
+ width: 45;
+ height: 17%;
+}
+.multi-mix {
+ width: 10px;
+ height: 29%;
+ margin: 4;
+ padding: 5;
+}
+body {
+ padding: 30px;
+ color: #ff0000;
+}
+.scope-mix {
+ width: 8;
+}
+.content {
+ width: 600px;
+}
+.content .column {
+ margin: 600px;
+}
+#same-var-name {
+ radius: 5px;
+}
+#var-inside {
+ width: 10px;
+}
+.arguments {
+ border: 1px solid #000000;
+ width: 1px;
+}
+.arguments2 {
+ border: 0px;
+ width: 0px;
+}
+.arguments3 {
+ border: 0px;
+ width: 0px;
+}
+.arguments4 {
+ border: 0 1 2 3 4;
+ rest: 1 2 3 4;
+ width: 0;
+}
+.edge-case {
+ border: "{";
+ width: "{";
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinsclosurecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-closure.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-closure.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-closure.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+.class {
+ width: 99px;
+}
+.overwrite {
+ width: 99px;
+}
+.nested .class {
+ width: 5px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinsguardscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-guards.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-guards.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-guards.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,68 @@
</span><ins>+.light1 {
+ color: white;
+ margin: 1px;
+}
+.light2 {
+ color: black;
+ margin: 1px;
+}
+.max1 {
+ width: 6;
+}
+.max2 {
+ width: 8;
+}
+.glob1 {
+ margin: auto auto;
+}
+.ops1 {
+ height: gt-or-eq;
+ height: lt-or-eq;
+}
+.ops2 {
+ height: gt-or-eq;
+ height: not-eq;
+}
+.ops3 {
+ height: lt-or-eq;
+ height: not-eq;
+}
+.default1 {
+ content: default;
+}
+.test1 {
+ content: "true.";
+}
+.test2 {
+ content: "false.";
+}
+.test3 {
+ content: "false.";
+}
+.test4 {
+ content: "false.";
+}
+.test5 {
+ content: "false.";
+}
+.bool1 {
+ content: true and true;
+ content: true;
+ content: false, true;
+ content: false and true and true, true;
+ content: false, true and true;
+ content: false, false, true;
+ content: false, true and true and true, false;
+ content: not false;
+ content: not false and false, not false;
+}
+.colorguardtest {
+ content: is #ff0000;
+ content: is not #0000ff its #ff0000;
+ content: is not #0000ff its #800080;
+}
+.stringguardtest {
+ content: is theme1;
+ content: is not theme2;
+ content: is theme1 no quotes;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinsimportantcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-important.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-important.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-important.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+.class {
+ border: 1;
+ boxer: 1;
+ border: 2 !important;
+ boxer: 2 !important;
+ border: 3;
+ boxer: 3;
+ border: 4 !important;
+ boxer: 4 !important;
+ border: 5;
+ boxer: 5;
+ border: 0 !important;
+ boxer: 0 !important;
+ border: 9 !important;
+ border: 9;
+ boxer: 9;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinsnamedargscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-named-args.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-named-args.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-named-args.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+.named-arg {
+ color: blue;
+ width: 5px;
+ height: 99%;
+ text-align: center;
+}
+.class {
+ width: 5px;
+ height: 19%;
+}
+.named-args2 {
+ width: 15px;
+ height: 49%;
+ color: #646464;
+}
+.named-args3 {
+ width: 5px;
+ height: 29%;
+ color: #123456;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinsnestedcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-nested.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-nested.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-nested.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+.class .inner {
+ height: 300;
+}
+.class .inner .innest {
+ width: 30;
+ border-width: 60;
+}
+.class2 .inner {
+ height: 600;
+}
+.class2 .inner .innest {
+ width: 60;
+ border-width: 120;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinspatterncss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-pattern.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-pattern.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins-pattern.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,47 @@
</span><ins>+.zero {
+ variadic: true;
+ zero: 0;
+ one: 1;
+ two: 2;
+ three: 3;
+}
+.one {
+ variadic: true;
+ one: 1;
+ one-req: 1;
+ two: 2;
+ three: 3;
+}
+.two {
+ variadic: true;
+ two: 2;
+ three: 3;
+}
+.three {
+ variadic: true;
+ three-req: 3;
+ three: 3;
+}
+.left {
+ left: 1;
+}
+.right {
+ right: 1;
+}
+.border-right {
+ color: black;
+ border-right: 4px;
+}
+.border-left {
+ color: black;
+ border-left: 4px;
+}
+.only-right {
+ right: 33;
+}
+.only-left {
+ left: 33;
+}
+.left-right {
+ both: 330;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssmixinscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/mixins.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,108 @@
</span><ins>+.mixin {
+ border: 1px solid black;
+}
+.mixout {
+ border-color: orange;
+}
+.borders {
+ border-style: dashed;
+}
+#namespace .borders {
+ border-style: dotted;
+}
+#namespace .biohazard {
+ content: "death";
+}
+#namespace .biohazard .man {
+ color: transparent;
+}
+#theme > .mixin {
+ background-color: grey;
+}
+#container {
+ color: black;
+ border: 1px solid black;
+ border-color: orange;
+ background-color: grey;
+}
+#header .milk {
+ color: white;
+ border: 1px solid black;
+ background-color: grey;
+}
+#header #cookie {
+ border-style: dashed;
+}
+#header #cookie .chips {
+ border-style: dotted;
+}
+#header #cookie .chips .calories {
+ color: black;
+ border: 1px solid black;
+ border-color: orange;
+ background-color: grey;
+}
+.secure-zone {
+ color: transparent;
+}
+.direct {
+ border-style: dotted;
+}
+.bo,
+.bar {
+ width: 100%;
+}
+.bo {
+ border: 1px;
+}
+.ar.bo.ca {
+ color: black;
+}
+.jo.ki {
+ background: none;
+}
+.extended {
+ width: 100%;
+ border: 1px;
+ background: none;
+}
+.foo .bar {
+ width: 100%;
+}
+.underParents {
+ color: red;
+}
+.parent .underParents {
+ color: red;
+}
+* + h1 {
+ margin-top: 25px;
+}
+legend + h1 {
+ margin-top: 0;
+}
+h1 + * {
+ margin-top: 10px;
+}
+* + h2 {
+ margin-top: 20px;
+}
+legend + h2 {
+ margin-top: 0;
+}
+h2 + * {
+ margin-top: 8px;
+}
+* + h3 {
+ margin-top: 15px;
+}
+legend + h3 {
+ margin-top: 0;
+}
+h3 + * {
+ margin-top: 5px;
+}
+.error {
+ background-image: "/a.png";
+ background-position: center center;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssoperationscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/operations.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/operations.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/operations.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+#operations {
+ color: #111111;
+ height: 9px;
+ width: 3em;
+ substraction: 0;
+ division: 1;
+}
+#operations .spacing {
+ height: 9px;
+ width: 3em;
+}
+.with-variables {
+ height: 16em;
+ width: 24em;
+ size: 1cm;
+}
+.with-functions {
+ color: #646464;
+ color: #ff8080;
+ color: #c94a4a;
+}
+.negative {
+ height: 0px;
+ width: 4px;
+}
+.shorthands {
+ padding: -1px 2px 0 -4px;
+}
+.rem-dimensions {
+ font-size: 5.5rem;
+}
+.colors {
+ color: #123;
+ border-color: #334455;
+ background-color: #000000;
+}
+.colors .other {
+ color: #222222;
+ border-color: #222222;
+}
+.negations {
+ variable: -4px;
+ variable1: 0px;
+ variable2: 0px;
+ variable3: 8px;
+ variable4: 0px;
+ paren: -4px;
+ paren2: 16px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssparenscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/parens.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/parens.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/parens.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+.parens {
+ border: 2px solid #000000;
+ margin: 1px 3px 16 3;
+ width: 36;
+ padding: 2px 36px;
+}
+.more-parens {
+ padding: 8 4 4 4px;
+ width: 96;
+ height: 113;
+ margin: 12;
+}
+.nested-parens {
+ width: 71;
+ height: 6;
+}
+.mixed-units {
+ margin: 2px 4em 1 5pc;
+ padding: 6px 1em 2px 2;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssrulesetscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/rulesets.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/rulesets.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/rulesets.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+#first > .one {
+ font-size: 2em;
+}
+#first > .one > #second .two > #deux {
+ width: 50%;
+}
+#first > .one > #second .two > #deux #third {
+ height: 100%;
+}
+#first > .one > #second .two > #deux #third:focus {
+ color: black;
+}
+#first > .one > #second .two > #deux #third:focus #fifth > #sixth .seventh #eighth + #ninth {
+ color: purple;
+}
+#first > .one > #second .two > #deux #fourth,
+#first > .one > #second .two > #deux #five,
+#first > .one > #second .two > #deux #six {
+ color: #110000;
+}
+#first > .one > #second .two > #deux #fourth .seven,
+#first > .one > #second .two > #deux #five .seven,
+#first > .one > #second .two > #deux #six .seven,
+#first > .one > #second .two > #deux #fourth .eight > #nine,
+#first > .one > #second .two > #deux #five .eight > #nine,
+#first > .one > #second .two > #deux #six .eight > #nine {
+ border: 1px solid black;
+}
+#first > .one > #second .two > #deux #fourth #ten,
+#first > .one > #second .two > #deux #five #ten,
+#first > .one > #second .two > #deux #six #ten {
+ color: red;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssscopecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/scope.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/scope.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/scope.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+.tiny-scope {
+ color: #998899;
+}
+.scope1 {
+ color: #0000ff;
+ border-color: #000000;
+}
+.scope1 .scope2 {
+ color: #0000ff;
+}
+.scope1 .scope2 .scope3 {
+ color: #ff0000;
+ border-color: #000000;
+ background-color: #ffffff;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssselectorscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/selectors.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/selectors.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/selectors.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,130 @@
</span><ins>+h1 a:hover,
+h2 a:hover,
+h3 a:hover,
+h1 p:hover,
+h2 p:hover,
+h3 p:hover {
+ color: red;
+}
+#all {
+ color: blue;
+}
+#the {
+ color: blue;
+}
+#same {
+ color: blue;
+}
+ul,
+li,
+div,
+q,
+blockquote,
+textarea {
+ margin: 0;
+}
+td {
+ margin: 0;
+ padding: 0;
+}
+td,
+input {
+ line-height: 1em;
+}
+a {
+ color: red;
+}
+a:hover {
+ color: blue;
+}
+div a {
+ color: green;
+}
+p a span {
+ color: yellow;
+}
+.foo .bar .qux,
+.foo .baz .qux {
+ display: block;
+}
+.qux .foo .bar,
+.qux .foo .baz {
+ display: inline;
+}
+.qux.foo .bar,
+.qux.foo .baz {
+ display: inline-block;
+}
+.qux .foo .bar .biz,
+.qux .foo .baz .biz {
+ display: none;
+}
+.a.b.c {
+ color: red;
+}
+.c .b.a {
+ color: red;
+}
+.foo .p.bar {
+ color: red;
+}
+.foo.p.bar {
+ color: red;
+}
+.foo + .foo {
+ background: amber;
+}
+.foo + .foo {
+ background: amber;
+}
+.foo + .foo,
+.foo + .bar,
+.bar + .foo,
+.bar + .bar {
+ background: amber;
+}
+.foo a > .foo a,
+.foo a > .bar a,
+.foo a > .foo b,
+.foo a > .bar b,
+.bar a > .foo a,
+.bar a > .bar a,
+.bar a > .foo b,
+.bar a > .bar b,
+.foo b > .foo a,
+.foo b > .bar a,
+.foo b > .foo b,
+.foo b > .bar b,
+.bar b > .foo a,
+.bar b > .bar a,
+.bar b > .foo b,
+.bar b > .bar b {
+ background: amber;
+}
+.other ::fnord {
+ color: #ff0000;
+}
+.other::fnord {
+ color: #ff0000;
+}
+.other ::bnord {
+ color: #ff0000;
+}
+.other::bnord {
+ color: #ff0000;
+}
+.blood {
+ color: red;
+}
+.blood {
+ color: red;
+}
+.bloodred {
+ color: green;
+}
+#blood.blood.red.black {
+ color: black;
+}
+:nth-child(3):nth-child(3) {
+ second-use: deprecated;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssstringscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/strings.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/strings.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/strings.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+#strings {
+ background-image: url("http://son-of-a-banana.com");
+ quotes: "~" "~";
+ content: "#*%:&^,)!.(~*})";
+ empty: "";
+ brackets: "{" "}";
+ escapes: "\"hello\" \\world";
+ escapes2: "\"llo";
+}
+#comments {
+ content: "/* hello */ // not-so-secret";
+}
+#single-quote {
+ quotes: "'" "'";
+ content: '""#!&""';
+ empty: '';
+ semi-colon: ';';
+}
+#escaped {
+ filter: DX.Transform.MS.BS.filter(opacity=50);
+}
+#one-line {
+ image: url(http://tooks.com);
+}
+#crazy {
+ image: url(http://), "}", url("http://}");
+}
+#interpolation {
+ url: "http://lesscss.org/dev/image.jpg";
+ url2: "http://lesscss.org/image-256.jpg";
+ url3: "http://lesscss.org#445566";
+ url4: "http://lesscss.org/hello";
+ url5: "http://lesscss.org/54.4";
+}
+.mix-mul-class {
+ color: #0000ff;
+ color: #ff0000;
+ color: #000000;
+ color: #ffa500;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcssvariablescss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/variables.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/variables.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/variables.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+.variables {
+ width: 14cm;
+}
+.variables {
+ height: 24px;
+ color: #888888;
+ font-family: "Trebuchet MS", Verdana, sans-serif;
+ quotes: "~" "~";
+}
+.redefinition {
+ three: 3;
+}
+.values {
+ font-family: 'Trebuchet', 'Trebuchet', 'Trebuchet';
+ color: #888888 !important;
+ url: url('Trebuchet');
+ multi: something 'A', B, C, 'Trebuchet';
+}
+.variable-names {
+ name: 'hello';
+}
+.alpha {
+ filter: alpha(opacity=42);
+}
+a:nth-child(2) {
+ border: 1px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestcsswhitespacecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/whitespace.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/whitespace.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/css/whitespace.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+.whitespace {
+ color: white;
+}
+.whitespace {
+ color: white;
+}
+.whitespace {
+ color: white;
+}
+.whitespace {
+ color: white;
+}
+.whitespace {
+ color: white ;
+}
+.white,
+.space,
+.mania {
+ color: white;
+}
+.no-semi-column {
+ color: #ffffff;
+}
+.no-semi-column {
+ color: white;
+ white-space: pre;
+}
+.no-semi-column {
+ border: 2px solid #ffffff;
+}
+.newlines {
+ background: the,
+ great,
+ wall;
+ border: 2px
+ solid
+ black;
+}
+.sel .newline_ws .tab_ws {
+ color: white;
+ background-position: 45 -23;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesscolorsless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/colors.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/colors.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/colors.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,88 @@
</span><ins>+#yelow {
+ #short {
+ color: #fea;
+ }
+ #long {
+ color: #ffeeaa;
+ }
+ #rgba {
+ color: rgba(255, 238, 170, 0.1);
+ }
+ #argb {
+ color: argb(rgba(255, 238, 170, 0.1));
+ }
+}
+
+#blue {
+ #short {
+ color: #00f;
+ }
+ #long {
+ color: #0000ff;
+ }
+ #rgba {
+ color: rgba(0, 0, 255, 0.1);
+ }
+ #argb {
+ color: argb(rgba(0, 0, 255, 0.1));
+ }
+}
+
+#alpha #hsla {
+ color: hsla(11, 20%, 20%, 0.6);
+}
+
+#overflow {
+ .a { color: #111111 - #444444; } // #000000
+ .b { color: #eee + #fff; } // #ffffff
+ .c { color: #aaa * 3; } // #ffffff
+ .d { color: #00ee00 + #009900; } // #00ff00
+}
+
+#grey {
+ color: rgb(200, 200, 200);
+}
+
+#808080 {
+ color: hsl(50, 0%, 50%);
+}
+
+#00ff00 {
+ color: hsl(120, 100%, 50%);
+}
+
+.lightenblue {
+ color: lighten(blue, 10%);
+}
+
+.darkenblue {
+ color: darken(blue, 10%);
+}
+
+.unknowncolors {
+ color: blue2;
+ border: 2px solid superred;
+}
+
+.transparent {
+ color: transparent;
+ background-color: rgba(0, 0, 0, 0);
+}
+#alpha {
+ @colorvar: rgba(150, 200, 150, 0.7);
+ #fromvar {
+ opacity: alpha(@colorvar);
+ }
+ #short {
+ opacity: alpha(#aaa);
+ }
+ #long {
+ opacity: alpha(#bababa);
+ }
+ #rgba {
+ opacity: alpha(rgba(50, 120, 95, 0.2));
+ }
+ #hsl {
+ opacity: alpha(hsl(120, 100%, 50%));
+ }
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesscommentsless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/comments.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/comments.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/comments.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+/******************\
+* *
+* Comment Header *
+* *
+\******************/
+
+/*
+
+ Comment
+
+*/
+
+/*
+ * Comment Test
+ *
+ * - cloudhead (http://cloudhead.net)
+ *
+ */
+
+////////////////
+@var: "content";
+////////////////
+
+/* Colors
+ * ------
+ * #EDF8FC (background blue)
+ * #166C89 (darkest blue)
+ *
+ * Text:
+ * #333 (standard text) // A comment within a comment!
+ * #1F9EC9 (standard link)
+ *
+ */
+
+/* @group Variables
+------------------- */
+#comments /* boo */ {
+ /**/ // An empty comment
+ color: red; /* A C-style comment */
+ background-color: orange; // A little comment
+ font-size: 12px;
+
+ /* lost comment */ content: @var;
+
+ border: 1px solid black;
+
+ // padding & margin //
+ padding: 0; // }{ '"
+ margin: 2em;
+} //
+
+/* commented out
+ #more-comments {
+ color: grey;
+ }
+*/
+
+.selector /* .with */, .lots, /* of */ .comments {
+ color: grey, /* blue */ orange;
+ -webkit-border-radius: 2px /* webkit only */;
+ -moz-border-radius: 2px * 4 /* moz only with operation */;
+}
+
+#last { color: blue }
+//
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesscss3less"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/css-3.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/css-3.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/css-3.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,108 @@
</span><ins>+.comma-delimited {
+ background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+ text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
+ -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset,
+ 0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
+}
+@font-face {
+ font-family: Headline;
+ src: local(Futura-Medium),
+ url(fonts.svg#MyGeometricModern) format("svg");
+}
+.other {
+ -moz-transform: translate(0, 11em) rotate(-90deg);
+ transform: rotateX(45deg);
+}
+.item[data-cra_zy-attr1b-ut3=bold] {
+ font-weight: bold;
+}
+p:not([class*="lead"]) {
+ color: black;
+}
+
+input[type="text"].class#id[attr=32]:not(1) {
+ color: white;
+}
+
+div#id.class[a=1][b=2].class:not(1) {
+ color: white;
+}
+
+ul.comma > li:not(:only-child)::after {
+ color: white;
+}
+
+ol.comma > li:nth-last-child(2)::after {
+ color: white;
+}
+
+li:nth-child(4n+1),
+li:nth-child(-5n),
+li:nth-child(-n+2) {
+ color: white;
+}
+
+a[href^="http://"] {
+ color: black;
+}
+
+a[href$="http://"] {
+ color: black;
+}
+
+form[data-disabled] {
+ color: black;
+}
+
+p::before {
+ color: black;
+}
+
+#issue322 {
+ -webkit-animation: anim2 7s infinite ease-in-out;
+}
+
+@-webkit-keyframes frames {
+ 0% { border: 1px }
+ 5.5% { border: 2px }
+ 100% { border: 3px }
+}
+
+@keyframes fontbulger1 {
+ to {
+ font-size: 15px;
+ }
+ from,to {
+ font-size: 12px;
+ }
+ 0%,100% {
+ font-size: 12px;
+ }
+}
+
+.units {
+ font: 1.2rem/2rem;
+ font: 8vw/9vw;
+ font: 10vh/12vh;
+ font: 12vm/15vm;
+ font: 12vmin/15vmin;
+ font: 1.2ch/1.5ch;
+}
+
+@supports ( box-shadow: 2px 2px 2px black ) or
+ ( -moz-box-shadow: 2px 2px 2px black ) {
+ .outline {
+ box-shadow: 2px 2px 2px black;
+ -moz-box-shadow: 2px 2px 2px black;
+ }
+}
+
+@-x-document url-prefix(""github.com"") {
+ h1 {
+ color: red;
+ }
+}
+
+@viewport {
+ font-size: 10px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesscssescapesless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/css-escapes.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/css-escapes.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/css-escapes.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+@ugly: fuchsia;
+
+.escape\|random\|char {
+ color: red;
+}
+
+.mixin\!tUp {
+ font-weight: bold;
+}
+
+// class="404"
+.\34 04 {
+ background: red;
+
+ strong {
+ color: @ugly;
+ .mixin\!tUp;
+ }
+}
+
+.trailingTest\+ {
+ color: red;
+}
+
+/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */
+\62\6c\6f \63 \6B \0071 \000075o\74 e {
+ color: silver;
+}
+
+[ng\:cloak],
+ng\:form {
+ display: none;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesscssless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/css.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/css.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/css.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,115 @@
</span><ins>+@charset "utf-8";
+div { color: black; }
+div { width: 99%; }
+
+* {
+ min-width: 45em;
+}
+
+h1, h2 > a > p, h3 {
+ color: none;
+}
+
+div.class {
+ color: blue;
+}
+
+div#id {
+ color: green;
+}
+
+.class#id {
+ color: purple;
+}
+
+.one.two.three {
+ color: grey;
+}
+
+@media print {
+ font-size: 3em;
+}
+
+@media screen {
+ font-size: 10px;
+}
+
+@font-face {
+ font-family: 'Garamond Pro';
+ src: url("/fonts/garamond-pro.ttf");
+}
+
+a:hover, a:link {
+ color: #999;
+}
+
+p, p:first-child {
+ text-transform: none;
+}
+
+q:lang(no) {
+ quotes: none;
+}
+
+p + h1 {
+ font-size: 2.2em;
+}
+
+#shorthands {
+ border: 1px solid #000;
+ font: 12px/16px Arial;
+ font: 100%/16px Arial;
+ margin: 1px 0;
+ padding: 0 auto;
+ background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+
+#more-shorthands {
+ margin: 0;
+ padding: 1px 0 2px 0;
+ font: normal small/20px 'Trebuchet MS', Verdana, sans-serif;
+ font: 0/0 a;
+}
+
+.misc {
+ -moz-border-radius: 2px;
+ display: -moz-inline-stack;
+ width: .1em;
+ background-color: #009998;
+ background-image: url(images/image.jpg);
+ background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
+ margin: ;
+ filter: alpha(opacity=100);
+}
+
+#important {
+ color: red !important;
+ width: 100%!important;
+ height: 20px ! important;
+}
+
+#data-uri {
+ background: url(data:image/png;charset=utf-8;base64,
+ kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+ k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+ kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+ background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+ background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+
+#svg-data-uri {
+ background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+
+.def-font(@name) {
+ @font-face {
+ font-family: @name
+ }
+}
+
+.def-font(font-a);
+.def-font(font-b);
+
+.æøå {
+ margin: 0;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessdebugimporttestless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/debug/import/test.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/debug/import/test.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/debug/import/test.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+.mixin_import1() {
+ @media all {
+ .tst {
+ color: black;
+ @media screen {
+ color: red;
+ .tst3 {
+ color: white;
+ }
+ }
+ }
+ }
+}
+
+.mixin_import2() {
+ .tst2 {
+ color: white;
+ }
+}
+
+.tst3 {
+ color: grey;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessdebuglinenumbersless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/debug/linenumbers.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/debug/linenumbers.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/debug/linenumbers.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+@import "import/test.less";
+
+.start() {
+ .test2 {
+ color: red;
+ }
+}
+
+.mix() {
+ color: black;
+}
+
+.test1 {
+ .mix();
+}
+
+.start();
+
+.mixin_import1();
+
+.mixin_import2();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorscommentinselectorless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/comment-in-selector.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/comment-in-selector.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/comment-in-selector.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+#gaga /* Comment */ span { color: red }
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorscommentinselectortxt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/comment-in-selector.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/comment-in-selector.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/comment-in-selector.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+ParseError: Syntax Error on line 1 in {path}comment-in-selector.less:1:20
+1 #gaga /* Comment */ span { color: red }
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportmissingless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-missing.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-missing.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-missing.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+@import "file-does-not-exist.less";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportmissingtxt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-missing.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-missing.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-missing.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+FileError: 'file-does-not-exist.less' wasn't found.
+ in {path}import-missing.less:1:0
+1 @import "file-does-not-exist.less";
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportnosemiless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-no-semi.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-no-semi.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-no-semi.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+@import "this-statement-is-invalid.less"
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportnosemitxt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-no-semi.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-no-semi.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-no-semi.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+ParseError: Syntax Error on line 1 in {path}import-no-semi.less:1:0
+1 @import "this-statement-is-invalid.less"
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportsubfolder1less"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder1.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder1.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder1.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+@import "imports/import-subfolder1.less";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportsubfolder1txt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder1.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder1.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder1.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+NameError: .mixin-not-defined is undefined in {pathrel}mixin-not-defined.less:11:0
+10
+11 .mixin-not-defined();
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportsubfolder2less"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder2.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder2.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder2.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+@import "imports/import-subfolder2.less";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportsubfolder2txt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder2.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder2.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/import-subfolder2.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+ParseError: Syntax Error on line 1 in {pathrel}parse-error-curly-bracket.less:1:0
+1 }}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportsimportsubfolder1less"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/import-subfolder1.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/import-subfolder1.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/import-subfolder1.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+@import "subfolder/mixin-not-defined.less";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportsimportsubfolder2less"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/import-subfolder2.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/import-subfolder2.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/import-subfolder2.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+@import "subfolder/parse-error-curly-bracket.less";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportssubfoldermixinnotdefinedless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/subfolder/mixin-not-defined.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/subfolder/mixin-not-defined.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/subfolder/mixin-not-defined.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+@import "../../mixin-not-defined.less";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsimportssubfolderparseerrorcurlybracketless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/subfolder/parse-error-curly-bracket.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/subfolder/parse-error-curly-bracket.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/imports/subfolder/parse-error-curly-bracket.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+@import "../../parse-error-curly-bracket.less";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsjavascripterrorless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/javascript-error.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/javascript-error.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/javascript-error.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+.scope {
+ var: `this.foo.toJS()`;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsjavascripterrortxt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/javascript-error.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/javascript-error.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/javascript-error.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+SyntaxError: JavaScript evaluation error: 'TypeError: Cannot call method 'toJS' of undefined' in {path}javascript-error.less:2:26
+1 .scope {
+2 var: `this.foo.toJS()`;
+3 }
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsmixinnotdefinedless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/mixin-not-defined.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/mixin-not-defined.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/mixin-not-defined.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+
+.error-is-further-on() {
+}
+
+.pad-here-to-reproduce-error-in() {
+}
+
+.the-import-subfolder-test() {
+}
+
+.mixin-not-defined();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsmixinnotdefinedtxt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/mixin-not-defined.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/mixin-not-defined.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/mixin-not-defined.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+NameError: .mixin-not-defined is undefined in {path}mixin-not-defined.less:11:0
+10
+11 .mixin-not-defined();
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsparseerrorcurlybracketless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-curly-bracket.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-curly-bracket.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-curly-bracket.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+}}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsparseerrorcurlybrackettxt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-curly-bracket.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-curly-bracket.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-curly-bracket.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+ParseError: Syntax Error on line 1 in {path}parse-error-curly-bracket.less:1:0
+1 }}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsparseerrormissingbracketless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-missing-bracket.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-missing-bracket.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-missing-bracket.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+body {
+ background-color: #fff;
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorsparseerrormissingbrackettxt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-missing-bracket.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-missing-bracket.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/parse-error-missing-bracket.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+ParseError: missing closing `}` in {path}parse-error-missing-bracket.less:3:1
+2 background-color: #fff;
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorspropertyie5hackless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/property-ie5-hack.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/property-ie5-hack.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/property-ie5-hack.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+.test {
+ display/*/: block; /*sorry for IE5*/
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesserrorspropertyie5hacktxt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/property-ie5-hack.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/property-ie5-hack.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/errors/property-ie5-hack.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+ParseError: Syntax Error on line 2 in {path}property-ie5-hack.less:2:2
+1 .test {
+2 display/*/: block; /*sorry for IE5*/
+3 }
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessfunctionsless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/functions.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/functions.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/functions.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,101 @@
</span><ins>+#functions {
+ @var: 10;
+ @colors: #000, #fff;
+ color: _color("evil red"); // #660000
+ width: increment(15);
+ height: undefined("self");
+ border-width: add(2, 3);
+ variable: increment(@var);
+ background: linear-gradient(@colors);
+}
+
+#built-in {
+ @r: 32;
+ escaped: e("-Some::weird(#thing, y)");
+ lighten: lighten(#ff0000, 40%);
+ darken: darken(#ff0000, 40%);
+ saturate: saturate(#29332f, 20%);
+ desaturate: desaturate(#203c31, 20%);
+ greyscale: greyscale(#203c31);
+ spin-p: spin(hsl(340, 50%, 50%), 40);
+ spin-n: spin(hsl(30, 50%, 50%), -40);
+ luma-white: luma(#fff);
+ luma-black: luma(#000);
+ luma-black-alpha: luma(rgba(0,0,0,0.5));
+ luma-red: luma(#ff0000);
+ luma-green: luma(#00ff00);
+ luma-blue: luma(#0000ff);
+ luma-yellow: luma(#ffff00);
+ luma-cyan: luma(#00ffff);
+ luma-white-alpha: luma(rgba(255,255,255,0.5));
+ contrast-white: contrast(#fff);
+ contrast-black: contrast(#000);
+ contrast-red: contrast(#ff0000);
+ contrast-green: contrast(#00ff00);
+ contrast-blue: contrast(#0000ff);
+ contrast-yellow: contrast(#ffff00);
+ contrast-cyan: contrast(#00ffff);
+ contrast-light: contrast(#fff, #111111, #eeeeee);
+ contrast-dark: contrast(#000, #111111, #eeeeee);
+ contrast-light-thresh: contrast(#fff, #111111, #eeeeee, 0.5);
+ contrast-dark-thresh: contrast(#000, #111111, #eeeeee, 0.5);
+ contrast-high-thresh: contrast(#555, #111111, #eeeeee, 0.6);
+ contrast-low-thresh: contrast(#555, #111111, #eeeeee, 0.1);
+ format: %("rgb(%d, %d, %d)", @r, 128, 64);
+ format-string: %("hello %s", "world");
+ format-multiple: %("hello %s %d", "earth", 2);
+ format-url-encode: %('red is %A', #ff0000);
+ eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64));
+
+ hue: hue(hsl(98, 12%, 95%));
+ saturation: saturation(hsl(98, 12%, 95%));
+ lightness: lightness(hsl(98, 12%, 95%));
+ red: red(#f00);
+ green: green(#0f0);
+ blue: blue(#00f);
+ rounded: round(@r/3);
+ rounded-two: round(@r/3, 2);
+ roundedpx: round(10px / 3);
+ roundedpx-three: round(10px / 3, 3);
+ percentage: percentage(10px / 50);
+ color: color("#ff0011");
+ tint: tint(#777777, 13);
+ tint-full: tint(#777777, 100);
+ tint-percent: tint(#777777, 13%);
+ shade: shade(#777777, 13);
+ shade-full: shade(#777777, 100);
+ shade-percent: shade(#777777, 13%);
+
+ mix: mix(#ff0000, #ffff00, 80);
+ mix-0: mix(#ff0000, #ffff00, 0);
+ mix-100: mix(#ff0000, #ffff00, 100);
+ mix-weightless: mix(#ff0000, #ffff00);
+
+ .is-a {
+ color: iscolor(#ddd);
+ color1: iscolor(red);
+ color2: iscolor(rgb(0, 0, 0));
+ keyword: iskeyword(hello);
+ number: isnumber(32);
+ string: isstring("hello");
+ pixel: ispixel(32px);
+ percent: ispercentage(32%);
+ em: isem(32em);
+ }
+}
+
+#alpha {
+ alpha: darken(hsla(25, 50%, 50%, 0.6), 10%);
+}
+
+#blendmodes {
+ multiply: multiply(#f60000, #f60000);
+ screen: screen(#f60000, #0000f6);
+ overlay: overlay(#f60000, #0000f6);
+ softlight: softlight(#f60000, #ffffff);
+ hardlight: hardlight(#f60000, #0000f6);
+ difference: difference(#f60000, #0000f6);
+ exclusion: exclusion(#f60000, #0000f6);
+ average: average(#f60000, #0000f6);
+ negation: negation(#f60000, #313131);
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessiefiltersless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/ie-filters.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/ie-filters.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/ie-filters.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+@fat: 0;
+@cloudhead: "#000000";
+
+.nav {
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity = 20);
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@fat);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr=@cloudhead, GradientType=@fat);
+}
+.evalTest(@arg) {
+ filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@arg);
+}
+.evalTest1 {
+ .evalTest(30);
+ .evalTest(5);
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportdeeperimportoncetestaless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/deeper/import-once-test-a.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/deeper/import-once-test-a.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/deeper/import-once-test-a.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+@import-once "../import-test-d.css";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportimportoncetestcless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-once-test-c.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-once-test-c.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-once-test-c.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+
+@import-once "import-test-d.css";
+@c: red;
+
+#import {
+ color: @c;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportimporttestaless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-a.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-a.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-a.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+@import "import-test-b.less";
+@a: 20%;
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportimporttestbless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-b.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-b.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-b.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+@import "import-test-c";
+
+@b: 100%;
+
+.mixin {
+ height: 10px;
+ color: @c;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportimporttestcless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-c.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-c.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-c.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+
+@import "import-test-d.css";
+@c: red;
+
+#import {
+ color: @c;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportimporttestdcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-d.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-d.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-d.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+#css { color: yellow; }
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportimporttesteless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-e.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-e.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import/import-test-e.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+
+body { width: 100% }
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportonceless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import-once.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import-once.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import-once.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+@import-once "import/import-once-test-c";
+@import-once "import/import-once-test-c";
+@import-once "import/deeper/import-once-test-a";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessimportless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/import.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+@import url("import/import-test-a.less");
+@import url(http://fonts.googleapis.com/css?family=Open+Sans);
+
+@import url(something.css) screen and (color) and (max-width: 600px);
+
+#import-test {
+ .mixin;
+ width: 10px;
+ height: @a + 10%;
+}
+@import "import/import-test-e" screen and (max-width: 600px);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessjavascriptless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/javascript.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/javascript.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/javascript.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+.eval {
+ js: `42`;
+ js: `1 + 1`;
+ js: `"hello world"`;
+ js: `[1, 2, 3]`;
+ title: `typeof process.title`;
+ ternary: `(1 + 1 == 2 ? true : false)`;
+ multiline: `(function(){var x = 1 + 1;
+ return x})()`;
+}
+.scope {
+ @foo: 42;
+ var: `this.foo.toJS()`;
+ escaped: ~`2 + 5 + 'px'`;
+}
+.vars {
+ @var: `4 + 4`;
+ width: @var;
+}
+.escape-interpol {
+ @world: "world";
+ width: ~`"hello" + " " + @{world}`;
+}
+.arrays {
+ @ary: 1, 2, 3;
+ @ary2: 1 2 3;
+ ary: `@{ary}.join(', ')`;
+ ary1: `@{ary2}.join(', ')`;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesslazyevalless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/lazy-eval.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/lazy-eval.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/lazy-eval.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+@var: @a;
+@a: 100%;
+
+.lazy-eval {
+ width: @var;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmedialess"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/media.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/media.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/media.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,179 @@
</span><ins>+
+// For now, variables can't be declared inside @media blocks.
+
+@var: 42;
+
+@media print {
+ .class {
+ color: blue;
+ .sub {
+ width: @var;
+ }
+ }
+ .top, header > h1 {
+ color: #222 * 2;
+ }
+}
+
+@media screen {
+ @base: 8;
+ body { max-width: @base * 60; }
+}
+
+@media all and (device-aspect-ratio: 16/9) {
+ body { max-width: 800px; }
+}
+
+@media all and (orientation:portrait) {
+ aside { float: none; }
+}
+
+@media handheld and (min-width: @var), screen and (min-width: 20em) {
+ body {
+ max-width: 480px;
+ }
+}
+
+body {
+ @media print {
+ padding: 20px;
+
+ header {
+ background-color: red;
+ }
+
+ @media (orientation:landscape) {
+ margin-left: 20px;
+ }
+ }
+}
+
+@media screen {
+ .sidebar {
+ width: 300px;
+ @media (orientation: landscape) {
+ width: 500px;
+ }
+ }
+}
+
+@media a {
+ .first {
+ @media b {
+ .second {
+ .third {
+ width: 300px;
+ @media c {
+ width: 500px;
+ }
+ }
+ .fourth {
+ width: 3;
+ }
+ }
+ }
+ }
+}
+
+body {
+ @media a, b and c {
+ width: 95%;
+
+ @media x, y {
+ width: 100%;
+ }
+ }
+}
+
+.mediaMixin(@fallback: 200px) {
+ background: black;
+
+ @media handheld {
+ background: white;
+
+ @media (max-width: @fallback) {
+ background: red;
+ }
+ }
+}
+
+.a {
+ .mediaMixin(100px);
+}
+
+.b {
+ .mediaMixin();
+}
+@smartphone: ~"only screen and (max-width: 200px)";
+@media @smartphone {
+ width: 480px;
+}
+
+@media print {
+ @page :left {
+ margin: 0.5cm;
+ }
+ @page :right {
+ margin: 0.5cm;
+ }
+ @page Test:first {
+ margin: 1cm;
+ }
+ @page :first {
+ size: 8.5in 11in;
+ @top-left {
+ margin: 1cm;
+ }
+ @top-left-corner {
+ margin: 1cm;
+ }
+ @top-center {
+ margin: 1cm;
+ }
+ @top-right {
+ margin: 1cm;
+ }
+ @top-right-corner {
+ margin: 1cm;
+ }
+ @bottom-left {
+ margin: 1cm;
+ }
+ @bottom-left-corner {
+ margin: 1cm;
+ }
+ @bottom-center {
+ margin: 1cm;
+ }
+ @bottom-right {
+ margin: 1cm;
+ }
+ @bottom-right-corner {
+ margin: 1cm;
+ }
+ @left-top {
+ margin: 1cm;
+ }
+ @left-middle {
+ margin: 1cm;
+ }
+ @left-bottom {
+ margin: 1cm;
+ }
+ @right-top {
+ margin: 1cm;
+ }
+ @right-middle {
+ content: "Page " counter(page);
+ }
+ @right-bottom {
+ margin: 1cm;
+ }
+ }
+}
+
+@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 128dpcm) {
+ .b {
+ background: red;
+ }
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsargsless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-args.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-args.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-args.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,130 @@
</span><ins>+.mixin (@a: 1px, @b: 50%) {
+ width: @a * 5;
+ height: @b - 1%;
+}
+
+.mixina (@style, @width, @color: black) {
+ border: @width @style @color;
+}
+
+.mixiny
+(@a: 0, @b: 0) {
+ margin: @a;
+ padding: @b;
+}
+
+.hidden() {
+ color: transparent; // asd
+}
+
+#hidden {
+ .hidden;
+}
+
+#hidden1 {
+ .hidden();
+}
+
+.two-args {
+ color: blue;
+ .mixin(2px, 100%);
+ .mixina(dotted, 2px);
+}
+
+.one-arg {
+ .mixin(3px);
+}
+
+.no-parens {
+ .mixin;
+}
+
+.no-args {
+ .mixin();
+}
+
+.var-args {
+ @var: 9;
+ .mixin(@var, @var * 2);
+}
+
+.multi-mix {
+ .mixin(2px, 30%);
+ .mixiny(4, 5);
+}
+
+.maxa(@arg1: 10, @arg2: #f00) {
+ padding: @arg1 * 2px;
+ color: @arg2;
+}
+
+body {
+ .maxa(15);
+}
+
+@glob: 5;
+.global-mixin(@a:2) {
+ width: @glob + @a;
+}
+
+.scope-mix {
+ .global-mixin(3);
+}
+
+.nested-ruleset (@width: 200px) {
+ width: @width;
+ .column { margin: @width; }
+}
+.content {
+ .nested-ruleset(600px);
+}
+
+//
+
+.same-var-name2(@radius) {
+ radius: @radius;
+}
+.same-var-name(@radius) {
+ .same-var-name2(@radius);
+}
+#same-var-name {
+ .same-var-name(5px);
+}
+
+//
+
+.var-inside () {
+ @var: 10px;
+ width: @var;
+}
+#var-inside { .var-inside; }
+
+.mixin-arguments (@width: 0px, ...) {
+ border: @arguments;
+ width: @width;
+}
+
+.arguments {
+ .mixin-arguments(1px, solid, black);
+}
+.arguments2 {
+ .mixin-arguments();
+}
+.arguments3 {
+ .mixin-arguments;
+}
+
+.mixin-arguments2 (@width, @rest...) {
+ border: @arguments;
+ rest: @rest;
+ width: @width;
+}
+.arguments4 {
+ .mixin-arguments2(0, 1, 2, 3, 4);
+}
+
+// Edge cases
+
+.edge-case {
+ .mixin-arguments("{");
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsclosureless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-closure.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-closure.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-closure.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+.scope {
+ @var: 99px;
+ .mixin () {
+ width: @var;
+ }
+}
+
+.class {
+ .scope > .mixin;
+}
+
+.overwrite {
+ @var: 0px;
+ .scope > .mixin;
+}
+
+.nested {
+ @var: 5px;
+ .mixin () {
+ width: @var;
+ }
+ .class {
+ @var: 10px;
+ .mixin;
+ }
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsguardsless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-guards.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-guards.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-guards.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,113 @@
</span><ins>+
+// Stacking, functions..
+
+.light (@a) when (lightness(@a) > 50%) {
+ color: white;
+}
+.light (@a) when (lightness(@a) < 50%) {
+ color: black;
+}
+.light (@a) {
+ margin: 1px;
+}
+
+.light1 { .light(#ddd) }
+.light2 { .light(#444) }
+
+// Arguments against each other
+
+.max (@a, @b) when (@a > @b) {
+ width: @a;
+}
+.max (@a, @b) when (@a < @b) {
+ width: @b;
+}
+
+.max1 { .max(3, 6) }
+.max2 { .max(8, 1) }
+
+// Globals inside guards
+
+@g: auto;
+
+.glob (@a) when (@a = @g) {
+ margin: @a @g;
+}
+.glob1 { .glob(auto) }
+
+// Other operators
+
+.ops (@a) when (@a >= 0) {
+ height: gt-or-eq;
+}
+.ops (@a) when (@a =< 0) {
+ height: lt-or-eq;
+}
+.ops (@a) when not(@a = 0) {
+ height: not-eq;
+}
+.ops1 { .ops(0) }
+.ops2 { .ops(1) }
+.ops3 { .ops(-1) }
+
+// Scope and default values
+
+@a: auto;
+
+.default (@a: inherit) when (@a = inherit) {
+ content: default;
+}
+.default1 { .default }
+
+// true & false keywords
+.test (@a) when (@a) {
+ content: "true.";
+}
+.test (@a) when not (@a) {
+ content: "false.";
+}
+
+.test1 { .test(true) }
+.test2 { .test(false) }
+.test3 { .test(1) }
+.test4 { .test(boo) }
+.test5 { .test("true") }
+
+// Boolean expressions
+
+.bool () when (true) and (false) { content: true and false } // FALSE
+.bool () when (true) and (true) { content: true and true } // TRUE
+.bool () when (true) { content: true } // TRUE
+.bool () when (false) and (false) { content: true } // FALSE
+.bool () when (false), (true) { content: false, true } // TRUE
+.bool () when (false) and (true) and (true), (true) { content: false and true and true, true } // TRUE
+.bool () when (true) and (true) and (false), (false) { content: true and true and false, false } // FALSE
+.bool () when (false), (true) and (true) { content: false, true and true } // TRUE
+.bool () when (false), (false), (true) { content: false, false, true } // TRUE
+.bool () when (false), (false) and (true), (false) { content: false, false and true, false } // FALSE
+.bool () when (false), (true) and (true) and (true), (false) { content: false, true and true and true, false } // TRUE
+.bool () when not (false) { content: not false }
+.bool () when not (true) and not (false) { content: not true and not false }
+.bool () when not (true) and not (true) { content: not true and not true }
+.bool () when not (false) and (false), not (false) { content: not false and false, not false }
+
+.bool1 { .bool }
+
+.colorguard(@col) when (@col = red) { content: is @col; }
+.colorguard(@col) when not (blue = @col) { content: is not blue its @col; }
+.colorguard(@col) {}
+.colorguardtest {
+ .colorguard(red);
+ .colorguard(blue);
+ .colorguard(purple);
+}
+
+.stringguard(@str) when (@str = "theme1") { content: is theme1; }
+.stringguard(@str) when not ("theme2" = @str) { content: is not theme2; }
+.stringguard(@str) when (~"theme1" = @str) { content: is theme1 no quotes; }
+.stringguard(@str) {}
+.stringguardtest {
+ .stringguard("theme1");
+ .stringguard("theme2");
+ .stringguard(theme1);
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsimportantless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-important.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-important.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-important.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+
+.mixin (9) {
+ border: 9 !important;
+}
+.mixin (@a: 0) {
+ border: @a;
+ boxer: @a;
+}
+
+.class {
+ .mixin(1);
+ .mixin(2) !important;
+ .mixin(3);
+ .mixin(4) !important;
+ .mixin(5);
+ .mixin !important;
+ .mixin(9);
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsnamedargsless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-named-args.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-named-args.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-named-args.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+.mixin (@a: 1px, @b: 50%) {
+ width: @a * 5;
+ height: @b - 1%;
+}
+.mixin (@a: 1px, @b: 50%) when (@b > 75%){
+ text-align: center;
+}
+
+.named-arg {
+ color: blue;
+ .mixin(@b: 100%);
+}
+
+.class {
+ @var: 20%;
+ .mixin(@b: @var);
+}
+
+.mixin2 (@a: 1px, @b: 50%, @c: 50) {
+ width: @a * 5;
+ height: @b - 1%;
+ color: #000000 + @c;
+}
+
+.named-args2 {
+ .mixin2(3px, @c: 100);
+}
+
+.named-args3 {
+ .mixin2(@b: 30%, @c: #123456);
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsnestedless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-nested.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-nested.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-nested.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+.mix-inner (@var) {
+ border-width: @var;
+}
+
+.mix (@a: 10) {
+ .inner {
+ height: @a * 10;
+
+ .innest {
+ width: @a;
+ .mix-inner(@a * 2);
+ }
+ }
+}
+
+.class {
+ .mix(30);
+}
+
+.class2 {
+ .mix(60);
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinspatternless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-pattern.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-pattern.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins-pattern.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,99 @@
</span><ins>+.mixin (...) {
+ variadic: true;
+}
+.mixin () {
+ zero: 0;
+}
+.mixin (@a: 1px) {
+ one: 1;
+}
+.mixin (@a) {
+ one-req: 1;
+}
+.mixin (@a: 1px, @b: 2px) {
+ two: 2;
+}
+
+.mixin (@a, @b, @c) {
+ three-req: 3;
+}
+
+.mixin (@a: 1px, @b: 2px, @c: 3px) {
+ three: 3;
+}
+
+.zero {
+ .mixin();
+}
+
+.one {
+ .mixin(1);
+}
+
+.two {
+ .mixin(1, 2);
+}
+
+.three {
+ .mixin(1, 2, 3);
+}
+
+//
+
+.mixout ('left') {
+ left: 1;
+}
+
+.mixout ('right') {
+ right: 1;
+}
+
+.left {
+ .mixout('left');
+}
+.right {
+ .mixout('right');
+}
+
+//
+
+.border (@side, @width) {
+ color: black;
+ .border-side(@side, @width);
+}
+.border-side (left, @w) {
+ border-left: @w;
+}
+.border-side (right, @w) {
+ border-right: @w;
+}
+
+.border-right {
+ .border(right, 4px);
+}
+.border-left {
+ .border(left, 4px);
+}
+
+//
+
+
+.border-radius (@r) {
+ both: @r * 10;
+}
+.border-radius (@r, left) {
+ left: @r;
+}
+.border-radius (@r, right) {
+ right: @r;
+}
+
+.only-right {
+ .border-radius(33, right);
+}
+.only-left {
+ .border-radius(33, left);
+}
+.left-right {
+ .border-radius(33);
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessmixinsless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/mixins.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,93 @@
</span><ins>+.mixin { border: 1px solid black; }
+.mixout { border-color: orange; }
+.borders { border-style: dashed; }
+
+#namespace {
+ .borders {
+ border-style: dotted;
+ }
+ .biohazard {
+ content: "death";
+ .man {
+ color: transparent;
+ }
+ }
+}
+#theme {
+ > .mixin {
+ background-color: grey;
+ }
+}
+#container {
+ color: black;
+ .mixin;
+ .mixout;
+ #theme > .mixin;
+}
+
+#header {
+ .milk {
+ color: white;
+ .mixin;
+ #theme > .mixin;
+ }
+ #cookie {
+ .chips {
+ #namespace .borders;
+ .calories {
+ #container;
+ }
+ }
+ .borders;
+ }
+}
+.secure-zone { #namespace .biohazard .man; }
+.direct {
+ #namespace > .borders;
+}
+
+.bo, .bar {
+ width: 100%;
+}
+.bo {
+ border: 1px;
+}
+.ar.bo.ca {
+ color: black;
+}
+.jo.ki {
+ background: none;
+}
+.extended {
+ .bo;
+ .jo.ki;
+}
+.foo .bar {
+ .bar;
+}
+.has_parents() {
+ & .underParents {
+ color: red;
+ }
+}
+.has_parents();
+.parent {
+ .has_parents();
+}
+.margin_between(@above, @below) {
+ * + & { margin-top: @above; }
+ legend + & { margin-top: 0; }
+ & + * { margin-top: @below; }
+}
+h1 { .margin_between(25px, 10px); }
+h2 { .margin_between(20px, 8px); }
+h3 { .margin_between(15px, 5px); }
+
+.mixin_def(@url, @position){
+ background-image: @url;
+ background-position: @position;
+}
+.error{
+ @s: "/";
+ .mixin_def( "@{s}a.png", center center);
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessoperationsless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/operations.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/operations.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/operations.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,62 @@
</span><ins>+#operations {
+ color: #110000 + #000011 + #001100; // #111111
+ height: 10px / 2px + 6px - 1px * 2; // 9px
+ width: 2 * 4 - 5em; // 3em
+ .spacing {
+ height: 10px / 2px+6px-1px*2;
+ width: 2 * 4-5em;
+ }
+ substraction: 20 - 10 - 5 - 5; // 0
+ division: 20 / 5 / 4; // 1
+}
+
+@x: 4;
+@y: 12em;
+
+.with-variables {
+ height: @x + @y; // 16em
+ width: 12 + @y; // 24em
+ size: 5cm - @x; // 1cm
+}
+
+.with-functions {
+ color: rgb(200, 200, 200) / 2;
+ color: 2 * hsl(0, 50%, 50%);
+ color: rgb(10, 10, 10) + hsl(0, 50%, 50%);
+}
+
+@z: -2;
+
+.negative {
+ height: 2px + @z; // 0px
+ width: 2px - @z; // 4px
+}
+
+.shorthands {
+ padding: -1px 2px 0 -4px; //
+}
+
+.rem-dimensions {
+ font-size: 20rem / 5 + 1.5rem; // 5.5rem
+}
+
+.colors {
+ color: #123; // #112233
+ border-color: #234 + #111111; // #334455
+ background-color: #222222 - #fff; // #000000
+ .other {
+ color: 2 * #111; // #222222
+ border-color: #333333 / 3 + #111; // #222222
+ }
+}
+
+.negations {
+ @var: 4px;
+ variable: -@var; // 4
+ variable1: -@var + @var; // 0
+ variable2: @var + -@var; // 0
+ variable3: @var - -@var; // 8
+ variable4: -@var - -@var; // 0
+ paren: -(@var); // -4px
+ paren2: -(2 + 2) * -@var; // 16
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessparensless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/parens.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/parens.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/parens.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+.parens {
+ @var: 1px;
+ border: (@var * 2) solid black;
+ margin: (@var * 1) (@var + 2) (4 * 4) 3;
+ width: (6 * 6);
+ padding: 2px (6px * 6px);
+}
+
+.more-parens {
+ @var: (2 * 2);
+ padding: (2 * @var) 4 4 (@var * 1px);
+ width: (@var * @var) * 6;
+ height: (7 * 7) + (8 * 8);
+ margin: 4 * (5 + 5) / 2 - (@var * 2);
+ //margin: (6 * 6)px;
+}
+
+.nested-parens {
+ width: 2 * (4 * (2 + (1 + 6))) - 1;
+ height: ((2+3)*(2+3) / (9-4)) + 1;
+}
+
+.mixed-units {
+ margin: 2px 4em 1 5pc;
+ padding: (2px + 4px) 1em 2px 2;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessrulesetsless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/rulesets.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/rulesets.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/rulesets.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+#first > .one {
+ > #second .two > #deux {
+ width: 50%;
+ #third {
+ &:focus {
+ color: black;
+ #fifth {
+ > #sixth {
+ .seventh #eighth {
+ + #ninth {
+ color: purple;
+ }
+ }
+ }
+ }
+ }
+ height: 100%;
+ }
+ #fourth, #five, #six {
+ color: #110000;
+ .seven, .eight > #nine {
+ border: 1px solid black;
+ }
+ #ten {
+ color: red;
+ }
+ }
+ }
+ font-size: 2em;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessscopeless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/scope.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/scope.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/scope.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+@x: blue;
+@z: transparent;
+@mix: none;
+
+.mixin {
+ @mix: #989;
+}
+
+.tiny-scope {
+ color: @mix; // #989
+ .mixin;
+}
+
+.scope1 {
+ @y: orange;
+ @z: black;
+ color: @x; // blue
+ border-color: @z; // black
+ .hidden {
+ @x: #131313;
+ }
+ .scope2 {
+ @y: red;
+ color: @x; // blue
+ .scope3 {
+ @local: white;
+ color: @y; // red
+ border-color: @z; // black
+ background-color: @local; // white
+ }
+ }
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessselectorsless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/selectors.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/selectors.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/selectors.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,131 @@
</span><ins>+h1, h2, h3 {
+ a, p {
+ &:hover {
+ color: red;
+ }
+ }
+}
+
+#all { color: blue; }
+#the { color: blue; }
+#same { color: blue; }
+
+ul, li, div, q, blockquote, textarea {
+ margin: 0;
+}
+
+td {
+ margin: 0;
+ padding: 0;
+}
+
+td, input {
+ line-height: 1em;
+}
+
+a {
+ color: red;
+
+ &:hover { color: blue; }
+
+ div & { color: green; }
+
+ p & span { color: yellow; }
+}
+
+.foo {
+ .bar, .baz {
+ & .qux {
+ display: block;
+ }
+ .qux & {
+ display: inline;
+ }
+ .qux& {
+ display: inline-block;
+ }
+ .qux & .biz {
+ display: none;
+ }
+ }
+}
+
+.b {
+ &.c {
+ .a& {
+ color: red;
+ }
+ }
+}
+
+.b {
+ .c & {
+ &.a {
+ color: red;
+ }
+ }
+}
+
+.p {
+ .foo &.bar {
+ color: red;
+ }
+}
+
+.p {
+ .foo&.bar {
+ color: red;
+ }
+}
+
+.foo {
+ .foo + & {
+ background: amber;
+ }
+ & + & {
+ background: amber;
+ }
+}
+
+.foo, .bar {
+ & + & {
+ background: amber;
+ }
+}
+
+.foo, .bar {
+ a, b {
+ & > & {
+ background: amber;
+ }
+ }
+}
+
+.other ::fnord { color: red }
+.other::fnord { color: red }
+.other {
+ ::bnord {color: red }
+ &::bnord {color: red }
+}
+// selector interpolation - deprecated
+@theme: blood;
+(~".@{theme}") {
+ color: red;
+}
+// selector interpolation - new format
+@selector: ~".@{theme}";
+@{selector} {
+ color:red;
+}
+@{selector}red {
+ color: green;
+}
+.red {
+ #@{theme}.@{theme}&.black {
+ color:black;
+ }
+}
+@num: 3;
+:nth-child(@{num}):nth-child(@num) {
+ second-use: deprecated;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessstringsless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/strings.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/strings.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/strings.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+#strings {
+ background-image: url("http://son-of-a-banana.com");
+ quotes: "~" "~";
+ content: "#*%:&^,)!.(~*})";
+ empty: "";
+ brackets: "{" "}";
+ escapes: "\"hello\" \\world";
+ escapes2: "\"llo";
+}
+#comments {
+ content: "/* hello */ // not-so-secret";
+}
+#single-quote {
+ quotes: "'" "'";
+ content: '""#!&""';
+ empty: '';
+ semi-colon: ';';
+}
+#escaped {
+ filter: ~"DX.Transform.MS.BS.filter(opacity=50)";
+}
+#one-line { image: url(http://tooks.com) }
+#crazy { image: url(http://), "}", url("http://}") }
+#interpolation {
+ @var: '/dev';
+ url: "http://lesscss.org@{var}/image.jpg";
+
+ @var2: 256;
+ url2: "http://lesscss.org/image-@{var2}.jpg";
+
+ @var3: #456;
+ url3: "http://lesscss.org@{var3}";
+
+ @var4: hello;
+ url4: "http://lesscss.org/@{var4}";
+
+ @var5: 54.4px;
+ url5: "http://lesscss.org/@{var5}";
+}
+
+// multiple calls with string interpolation
+
+.mix-mul (@a: green) {
+ color: ~"@{a}";
+}
+.mix-mul-class {
+ .mix-mul(blue);
+ .mix-mul(red);
+ .mix-mul(black);
+ .mix-mul(orange);
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlessvariablesless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/variables.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/variables.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/variables.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+@a: 2;
+@x: @a * @a;
+@y: @x + 1;
+@z: @x * 2 + @y;
+
+.variables {
+ width: @z + 1cm; // 14cm
+}
+
+@b: @a * 10;
+@c: #888;
+
+@fonts: "Trebuchet MS", Verdana, sans-serif;
+@f: @fonts;
+
+@quotes: "~" "~";
+@q: @quotes;
+
+.variables {
+ height: @b + @x + 0px; // 24px
+ color: @c;
+ font-family: @f;
+ quotes: @q;
+}
+
+.redefinition {
+ @var: 4;
+ @var: 2;
+ @var: 3;
+ three: @var;
+}
+
+.values {
+ @a: 'Trebuchet';
+ @multi: 'A', B, C;
+ font-family: @a, @a, @a;
+ color: @c !important;
+ url: url(@a);
+ multi: something @multi, @a;
+}
+
+.variable-names {
+ @var: 'hello';
+ @name: 'var';
+ name: @@name;
+}
+.alpha {
+ @var: 42;
+ filter: alpha(opacity=@var);
+}
+
+a:nth-child(@a) {
+ border: 1px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesswhitespaceless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/whitespace.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/whitespace.less (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less/whitespace.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+
+
+.whitespace
+ { color: white; }
+
+.whitespace
+{
+ color: white;
+}
+ .whitespace
+{ color: white; }
+
+.whitespace{color:white;}
+.whitespace { color : white ; }
+
+.white,
+.space,
+.mania
+{ color: white; }
+
+.no-semi-column { color: white }
+.no-semi-column {
+ color: white;
+ white-space: pre
+}
+.no-semi-column {border: 2px solid white}
+.newlines {
+ background: the,
+ great,
+ wall;
+ border: 2px
+ solid
+ black;
+}
+.empty {
+
+}
+.sel
+.newline_ws .tab_ws {
+color:
+white;
+background-position: 45
+-23;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleslesstestlesstestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less-test.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less-test.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/less/test/less-test.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,174 @@
</span><ins>+var path = require('path'),
+ fs = require('fs'),
+ sys = require('util');
+
+var less = require('../lib/less');
+var stylize = require('../lib/less/lessc_helper').stylize;
+
+var oneTestOnly = process.argv[2];
+
+var totalTests = 0,
+ failedTests = 0,
+ passedTests = 0;
+
+less.tree.functions.add = function (a, b) {
+ return new(less.tree.Dimension)(a.value + b.value);
+};
+less.tree.functions.increment = function (a) {
+ return new(less.tree.Dimension)(a.value + 1);
+};
+less.tree.functions._color = function (str) {
+ if (str.value === "evil red") { return new(less.tree.Color)("600") }
+};
+
+sys.puts("\n" + stylize("LESS", 'underline') + "\n");
+
+runTestSet();
+
+runTestSet(null, "errors/", function(name, err, compiledLess, doReplacements) {
+ fs.readFile(path.join('test/less/', name) + '.txt', 'utf-8', function (e, expectedErr) {
+ sys.print("- " + name + ": ");
+ expectedErr = doReplacements(expectedErr, 'test/less/errors/');
+ if (!err) {
+ if (compiledLess) {
+ fail("No Error", 'red');
+ } else {
+ fail("No Error, No Output");
+ }
+ } else {
+ var errMessage = less.formatError(err);
+ if (errMessage === expectedErr) {
+ ok('OK');
+ } else {
+ difference("FAIL", expectedErr, errMessage);
+ }
+ }
+ sys.puts("");
+ });}, null, function(input, directory) {
+ return input.replace(
+ "{path}", path.join(process.cwd(), "/test/less/errors/"))
+ .replace("{pathrel}", path.join("test", "less", "errors/"))
+ .replace(/\r\n/g, '\n');
+ });
+
+runTestSet({dumpLineNumbers: 'comments'}, "debug/", null,
+ function(name) { return name + '-comments'; });
+runTestSet({dumpLineNumbers: 'mediaquery'}, "debug/", null,
+ function(name) { return name + '-mediaquery'; });
+runTestSet({dumpLineNumbers: 'all'}, "debug/", null,
+ function(name) { return name + '-all'; });
+
+function globalReplacements(input, directory) {
+ return input.replace(/\{path\}/g, path.join(process.cwd(), directory))
+ .replace(/\{pathimport\}/g, path.join(process.cwd(), directory + "import/"))
+ .replace(/\r\n/g, '\n');
+}
+
+function runTestSet(options, foldername, verifyFunction, nameModifier, doReplacements) {
+ foldername = foldername || "";
+
+ if(!doReplacements)
+ doReplacements = globalReplacements;
+
+ fs.readdirSync(path.join('test/less/', foldername)).forEach(function (file) {
+ if (! /\.less/.test(file)) { return }
+
+ var name = foldername + path.basename(file, '.less');
+
+ if (oneTestOnly && name !== oneTestOnly) { return; }
+
+ totalTests++;
+
+ toCSS(options, path.join('test/less/', foldername + file), function (err, less) {
+
+ if (verifyFunction) {
+ return verifyFunction(name, err, less, doReplacements);
+ }
+ var css_name = name;
+ if(nameModifier) css_name=nameModifier(name);
+ fs.readFile(path.join('test/css', css_name) + '.css', 'utf-8', function (e, css) {
+ sys.print("- " + css_name + ": ")
+
+ css = css && doReplacements(css, 'test/less/' + foldername);
+ if (less === css) { ok('OK'); }
+ else if (err) {
+ fail("ERROR: " + (err && err.message));
+ } else {
+ difference("FAIL", css, less);
+ }
+ sys.puts("");
+ });
+ });
+ });
+}
+
+function diff(left, right) {
+ sys.puts("");
+ require('diff').diffLines(left, right).forEach(function(item) {
+ if(item.added || item.removed) {
+ sys.print(stylize(item.value, item.added ? 'green' : 'red'));
+ } else {
+ sys.print(item.value);
+ }
+ });
+}
+
+function fail(msg) {
+ sys.print(stylize(msg, 'red'));
+ failedTests++;
+ endTest();
+}
+
+function difference(msg, left, right) {
+ sys.print(stylize(msg, 'yellow'));
+ failedTests++;
+
+ diff(left, right);
+ endTest();
+}
+
+function ok(msg) {
+ sys.print(stylize(msg, 'green'));
+ passedTests++;
+ endTest();
+}
+
+function endTest() {
+ if (failedTests + passedTests === totalTests) {
+ sys.puts("");
+ sys.puts("");
+ if (failedTests > 0) {
+ sys.print(failedTests);
+ sys.print(stylize(" Failed", "red"));
+ sys.print(", " + passedTests + " passed");
+ } else {
+ sys.print(stylize("All Passed ", "green"));
+ sys.print(passedTests + " run");
+ }
+ }
+}
+
+function toCSS(options, path, callback) {
+ var tree, css;
+ options = options || {};
+ fs.readFile(path, 'utf-8', function (e, str) {
+ if (e) { return callback(e) }
+
+ options.paths = [require('path').dirname(path)];
+ options.filename = require('path').resolve(process.cwd(), path);
+ options.optimization = options.optimization || 0;
+
+ new(less.Parser)(options).parse(str, function (err, tree) {
+ if (err) {
+ callback(err);
+ } else {
+ try {
+ css = tree.toCSS();
+ callback(null, css);
+ } catch (e) {
+ callback(e);
+ }
+ }
+ });
+ });
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjsnpmignore"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/.npmignore (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/.npmignore (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/.npmignore 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+.DS_Store
+.tmp*~
+*.local.*
+.pinf-*
+node_modules/
+npm-debug.log
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjsREADMEhtml"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/README.html</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/README.html
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/README.html 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/README.html 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/README.html
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+application/xml
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjsREADMEorg"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/README.org (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/README.org (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/README.org 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,578 @@
</span><ins>+#+TITLE: UglifyJS -- a JavaScript parser/compressor/beautifier
+#+KEYWORDS: javascript, js, parser, compiler, compressor, mangle, minify, minifier
+#+DESCRIPTION: a JavaScript parser/compressor/beautifier in JavaScript
+#+STYLE: <link rel="stylesheet" type="text/css" href="docstyle.css" />
+#+AUTHOR: Mihai Bazon
+#+EMAIL: mihai.bazon@gmail.com
+
+* UglifyJS --- a JavaScript parser/compressor/beautifier
+
+This package implements a general-purpose JavaScript
+parser/compressor/beautifier toolkit. It is developed on [[http://nodejs.org/][NodeJS]], but it
+should work on any JavaScript platform supporting the CommonJS module system
+(and if your platform of choice doesn't support CommonJS, you can easily
+implement it, or discard the =exports.*= lines from UglifyJS sources).
+
+The tokenizer/parser generates an abstract syntax tree from JS code. You
+can then traverse the AST to learn more about the code, or do various
+manipulations on it. This part is implemented in [[../lib/parse-js.js][parse-js.js]] and it's a
+port to JavaScript of the excellent [[http://marijn.haverbeke.nl/parse-js/][parse-js]] Common Lisp library from [[http://marijn.haverbeke.nl/][Marijn
+Haverbeke]].
+
+( See [[http://github.com/mishoo/cl-uglify-js][cl-uglify-js]] if you're looking for the Common Lisp version of
+UglifyJS. )
+
+The second part of this package, implemented in [[../lib/process.js][process.js]], inspects and
+manipulates the AST generated by the parser to provide the following:
+
+- ability to re-generate JavaScript code from the AST. Optionally
+ indented---you can use this if you want to “beautify” a program that has
+ been compressed, so that you can inspect the source. But you can also run
+ our code generator to print out an AST without any whitespace, so you
+ achieve compression as well.
+
+- shorten variable names (usually to single characters). Our mangler will
+ analyze the code and generate proper variable names, depending on scope
+ and usage, and is smart enough to deal with globals defined elsewhere, or
+ with =eval()= calls or =with{}= statements. In short, if =eval()= or
+ =with{}= are used in some scope, then all variables in that scope and any
+ variables in the parent scopes will remain unmangled, and any references
+ to such variables remain unmangled as well.
+
+- various small optimizations that may lead to faster code but certainly
+ lead to smaller code. Where possible, we do the following:
+
+ - foo["bar"] ==> foo.bar
+
+ - remove block brackets ={}=
+
+ - join consecutive var declarations:
+ var a = 10; var b = 20; ==> var a=10,b=20;
+
+ - resolve simple constant expressions: 1 +2 * 3 ==> 7. We only do the
+ replacement if the result occupies less bytes; for example 1/3 would
+ translate to 0.333333333333, so in this case we don't replace it.
+
+ - consecutive statements in blocks are merged into a sequence; in many
+ cases, this leaves blocks with a single statement, so then we can remove
+ the block brackets.
+
+ - various optimizations for IF statements:
+
+ - if (foo) bar(); else baz(); ==> foo?bar():baz();
+ - if (!foo) bar(); else baz(); ==> foo?baz():bar();
+ - if (foo) bar(); ==> foo&&bar();
+ - if (!foo) bar(); ==> foo||bar();
+ - if (foo) return bar(); else return baz(); ==> return foo?bar():baz();
+ - if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}
+
+ - remove some unreachable code and warn about it (code that follows a
+ =return=, =throw=, =break= or =continue= statement, except
+ function/variable declarations).
+
+ - act a limited version of a pre-processor (c.f. the pre-processor of
+ C/C++) to allow you to safely replace selected global symbols with
+ specified values. When combined with the optimisations above this can
+ make UglifyJS operate slightly more like a compilation process, in
+ that when certain symbols are replaced by constant values, entire code
+ blocks may be optimised away as unreachable.
+
+** <<Unsafe transformations>>
+
+The following transformations can in theory break code, although they're
+probably safe in most practical cases. To enable them you need to pass the
+=--unsafe= flag.
+
+*** Calls involving the global Array constructor
+
+The following transformations occur:
+
+#+BEGIN_SRC js
+new Array(1, 2, 3, 4) => [1,2,3,4]
+Array(a, b, c) => [a,b,c]
+new Array(5) => Array(5)
+new Array(a) => Array(a)
+#+END_SRC
+
+These are all safe if the Array name isn't redefined. JavaScript does allow
+one to globally redefine Array (and pretty much everything, in fact) but I
+personally don't see why would anyone do that.
+
+UglifyJS does handle the case where Array is redefined locally, or even
+globally but with a =function= or =var= declaration. Therefore, in the
+following cases UglifyJS *doesn't touch* calls or instantiations of Array:
+
+#+BEGIN_SRC js
+// case 1. globally declared variable
+ var Array;
+ new Array(1, 2, 3);
+ Array(a, b);
+
+ // or (can be declared later)
+ new Array(1, 2, 3);
+ var Array;
+
+ // or (can be a function)
+ new Array(1, 2, 3);
+ function Array() { ... }
+
+// case 2. declared in a function
+ (function(){
+ a = new Array(1, 2, 3);
+ b = Array(5, 6);
+ var Array;
+ })();
+
+ // or
+ (function(Array){
+ return Array(5, 6, 7);
+ })();
+
+ // or
+ (function(){
+ return new Array(1, 2, 3, 4);
+ function Array() { ... }
+ })();
+
+ // etc.
+#+END_SRC
+
+*** =obj.toString()= ==> =obj+“”=
+
+** Install (NPM)
+
+UglifyJS is now available through NPM --- =npm install uglify-js= should do
+the job.
+
+** Install latest code from GitHub
+
+#+BEGIN_SRC sh
+## clone the repository
+mkdir -p /where/you/wanna/put/it
+cd /where/you/wanna/put/it
+git clone git://github.com/mishoo/UglifyJS.git
+
+## make the module available to Node
+mkdir -p ~/.node_libraries/
+cd ~/.node_libraries/
+ln -s /where/you/wanna/put/it/UglifyJS/uglify-js.js
+
+## and if you want the CLI script too:
+mkdir -p ~/bin
+cd ~/bin
+ln -s /where/you/wanna/put/it/UglifyJS/bin/uglifyjs
+ # (then add ~/bin to your $PATH if it's not there already)
+#+END_SRC
+
+** Usage
+
+There is a command-line tool that exposes the functionality of this library
+for your shell-scripting needs:
+
+#+BEGIN_SRC sh
+uglifyjs [ options... ] [ filename ]
+#+END_SRC
+
+=filename= should be the last argument and should name the file from which
+to read the JavaScript code. If you don't specify it, it will read code
+from STDIN.
+
+Supported options:
+
+- =-b= or =--beautify= --- output indented code; when passed, additional
+ options control the beautifier:
+
+ - =-i N= or =--indent N= --- indentation level (number of spaces)
+
+ - =-q= or =--quote-keys= --- quote keys in literal objects (by default,
+ only keys that cannot be identifier names will be quotes).
+
+- =-c= or =----consolidate-primitive-values= --- consolidates null, Boolean,
+ and String values. Known as aliasing in the Closure Compiler. Worsens the
+ data compression ratio of gzip.
+
+- =--ascii= --- pass this argument to encode non-ASCII characters as
+ =\uXXXX= sequences. By default UglifyJS won't bother to do it and will
+ output Unicode characters instead. (the output is always encoded in UTF8,
+ but if you pass this option you'll only get ASCII).
+
+- =-nm= or =--no-mangle= --- don't mangle names.
+
+- =-nmf= or =--no-mangle-functions= -- in case you want to mangle variable
+ names, but not touch function names.
+
+- =-ns= or =--no-squeeze= --- don't call =ast_squeeze()= (which does various
+ optimizations that result in smaller, less readable code).
+
+- =-mt= or =--mangle-toplevel= --- mangle names in the toplevel scope too
+ (by default we don't do this).
+
+- =--no-seqs= --- when =ast_squeeze()= is called (thus, unless you pass
+ =--no-squeeze=) it will reduce consecutive statements in blocks into a
+ sequence. For example, "a = 10; b = 20; foo();" will be written as
+ "a=10,b=20,foo();". In various occasions, this allows us to discard the
+ block brackets (since the block becomes a single statement). This is ON
+ by default because it seems safe and saves a few hundred bytes on some
+ libs that I tested it on, but pass =--no-seqs= to disable it.
+
+- =--no-dead-code= --- by default, UglifyJS will remove code that is
+ obviously unreachable (code that follows a =return=, =throw=, =break= or
+ =continue= statement and is not a function/variable declaration). Pass
+ this option to disable this optimization.
+
+- =-nc= or =--no-copyright= --- by default, =uglifyjs= will keep the initial
+ comment tokens in the generated code (assumed to be copyright information
+ etc.). If you pass this it will discard it.
+
+- =-o filename= or =--output filename= --- put the result in =filename=. If
+ this isn't given, the result goes to standard output (or see next one).
+
+- =--overwrite= --- if the code is read from a file (not from STDIN) and you
+ pass =--overwrite= then the output will be written in the same file.
+
+- =--ast= --- pass this if you want to get the Abstract Syntax Tree instead
+ of JavaScript as output. Useful for debugging or learning more about the
+ internals.
+
+- =-v= or =--verbose= --- output some notes on STDERR (for now just how long
+ each operation takes).
+
+- =-d SYMBOL[=VALUE]= or =--define SYMBOL[=VALUE]= --- will replace
+ all instances of the specified symbol where used as an identifier
+ (except where symbol has properly declared by a var declaration or
+ use as function parameter or similar) with the specified value. This
+ argument may be specified multiple times to define multiple
+ symbols - if no value is specified the symbol will be replaced with
+ the value =true=, or you can specify a numeric value (such as
+ =1024=), a quoted string value (such as ="object"= or
+ ='https://github.com'=), or the name of another symbol or keyword
+ (such as =null= or =document=).
+ This allows you, for example, to assign meaningful names to key
+ constant values but discard the symbolic names in the uglified
+ version for brevity/efficiency, or when used wth care, allows
+ UglifyJS to operate as a form of *conditional compilation*
+ whereby defining appropriate values may, by dint of the constant
+ folding and dead code removal features above, remove entire
+ superfluous code blocks (e.g. completely remove instrumentation or
+ trace code for production use).
+ Where string values are being defined, the handling of quotes are
+ likely to be subject to the specifics of your command shell
+ environment, so you may need to experiment with quoting styles
+ depending on your platform, or you may find the option
+ =--define-from-module= more suitable for use.
+
+- =-define-from-module SOMEMODULE= --- will load the named module (as
+ per the NodeJS =require()= function) and iterate all the exported
+ properties of the module defining them as symbol names to be defined
+ (as if by the =--define= option) per the name of each property
+ (i.e. without the module name prefix) and given the value of the
+ property. This is a much easier way to handle and document groups of
+ symbols to be defined rather than a large number of =--define=
+ options.
+
+- =--unsafe= --- enable other additional optimizations that are known to be
+ unsafe in some contrived situations, but could still be generally useful.
+ For now only these:
+
+ - foo.toString() ==> foo+""
+ - new Array(x,...) ==> [x,...]
+ - new Array(x) ==> Array(x)
+
+- =--max-line-len= (default 32K characters) --- add a newline after around
+ 32K characters. I've seen both FF and Chrome croak when all the code was
+ on a single line of around 670K. Pass --max-line-len 0 to disable this
+ safety feature.
+
+- =--reserved-names= --- some libraries rely on certain names to be used, as
+ pointed out in issue #92 and #81, so this option allow you to exclude such
+ names from the mangler. For example, to keep names =require= and =$super=
+ intact you'd specify --reserved-names "require,$super".
+
+- =--inline-script= -- when you want to include the output literally in an
+ HTML =<script>= tag you can use this option to prevent =</script= from
+ showing up in the output.
+
+- =--lift-vars= -- when you pass this, UglifyJS will apply the following
+ transformations (see the notes in API, =ast_lift_variables=):
+
+ - put all =var= declarations at the start of the scope
+ - make sure a variable is declared only once
+ - discard unused function arguments
+ - discard unused inner (named) functions
+ - finally, try to merge assignments into that one =var= declaration, if
+ possible.
+
+*** API
+
+To use the library from JavaScript, you'd do the following (example for
+NodeJS):
+
+#+BEGIN_SRC js
+var jsp = require("uglify-js").parser;
+var pro = require("uglify-js").uglify;
+
+var orig_code = "... JS code here";
+var ast = jsp.parse(orig_code); // parse code and get the initial AST
+ast = pro.ast_mangle(ast); // get a new AST with mangled names
+ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
+var final_code = pro.gen_code(ast); // compressed code here
+#+END_SRC
+
+The above performs the full compression that is possible right now. As you
+can see, there are a sequence of steps which you can apply. For example if
+you want compressed output but for some reason you don't want to mangle
+variable names, you would simply skip the line that calls
+=pro.ast_mangle(ast)=.
+
+Some of these functions take optional arguments. Here's a description:
+
+- =jsp.parse(code, strict_semicolons)= -- parses JS code and returns an AST.
+ =strict_semicolons= is optional and defaults to =false=. If you pass
+ =true= then the parser will throw an error when it expects a semicolon and
+ it doesn't find it. For most JS code you don't want that, but it's useful
+ if you want to strictly sanitize your code.
+
+- =pro.ast_lift_variables(ast)= -- merge and move =var= declarations to the
+ scop of the scope; discard unused function arguments or variables; discard
+ unused (named) inner functions. It also tries to merge assignments
+ following the =var= declaration into it.
+
+ If your code is very hand-optimized concerning =var= declarations, this
+ lifting variable declarations might actually increase size. For me it
+ helps out. On jQuery it adds 865 bytes (243 after gzip). YMMV. Also
+ note that (since it's not enabled by default) this operation isn't yet
+ heavily tested (please report if you find issues!).
+
+ Note that although it might increase the image size (on jQuery it gains
+ 865 bytes, 243 after gzip) it's technically more correct: in certain
+ situations, dead code removal might drop variable declarations, which
+ would not happen if the variables are lifted in advance.
+
+ Here's an example of what it does:
+
+#+BEGIN_SRC js
+function f(a, b, c, d, e) {
+ var q;
+ var w;
+ w = 10;
+ q = 20;
+ for (var i = 1; i < 10; ++i) {
+ var boo = foo(a);
+ }
+ for (var i = 0; i < 1; ++i) {
+ var boo = bar(c);
+ }
+ function foo(){ ... }
+ function bar(){ ... }
+ function baz(){ ... }
+}
+
+// transforms into ==>
+
+function f(a, b, c) {
+ var i, boo, w = 10, q = 20;
+ for (i = 1; i < 10; ++i) {
+ boo = foo(a);
+ }
+ for (i = 0; i < 1; ++i) {
+ boo = bar(c);
+ }
+ function foo() { ... }
+ function bar() { ... }
+}
+#+END_SRC
+
+- =pro.ast_mangle(ast, options)= -- generates a new AST containing mangled
+ (compressed) variable and function names. It supports the following
+ options:
+
+ - =toplevel= -- mangle toplevel names (by default we don't touch them).
+ - =except= -- an array of names to exclude from compression.
+ - =defines= -- an object with properties named after symbols to
+ replace (see the =--define= option for the script) and the values
+ representing the AST replacement value.
+
+- =pro.ast_squeeze(ast, options)= -- employs further optimizations designed
+ to reduce the size of the code that =gen_code= would generate from the
+ AST. Returns a new AST. =options= can be a hash; the supported options
+ are:
+
+ - =make_seqs= (default true) which will cause consecutive statements in a
+ block to be merged using the "sequence" (comma) operator
+
+ - =dead_code= (default true) which will remove unreachable code.
+
+- =pro.gen_code(ast, options)= -- generates JS code from the AST. By
+ default it's minified, but using the =options= argument you can get nicely
+ formatted output. =options= is, well, optional :-) and if you pass it it
+ must be an object and supports the following properties (below you can see
+ the default values):
+
+ - =beautify: false= -- pass =true= if you want indented output
+ - =indent_start: 0= (only applies when =beautify= is =true=) -- initial
+ indentation in spaces
+ - =indent_level: 4= (only applies when =beautify= is =true=) --
+ indentation level, in spaces (pass an even number)
+ - =quote_keys: false= -- if you pass =true= it will quote all keys in
+ literal objects
+ - =space_colon: false= (only applies when =beautify= is =true=) -- wether
+ to put a space before the colon in object literals
+ - =ascii_only: false= -- pass =true= if you want to encode non-ASCII
+ characters as =\uXXXX=.
+ - =inline_script: false= -- pass =true= to escape occurrences of
+ =</script= in strings
+
+*** Beautifier shortcoming -- no more comments
+
+The beautifier can be used as a general purpose indentation tool. It's
+useful when you want to make a minified file readable. One limitation,
+though, is that it discards all comments, so you don't really want to use it
+to reformat your code, unless you don't have, or don't care about, comments.
+
+In fact it's not the beautifier who discards comments --- they are dumped at
+the parsing stage, when we build the initial AST. Comments don't really
+make sense in the AST, and while we could add nodes for them, it would be
+inconvenient because we'd have to add special rules to ignore them at all
+the processing stages.
+
+*** Use as a code pre-processor
+
+The =--define= option can be used, particularly when combined with the
+constant folding logic, as a form of pre-processor to enable or remove
+particular constructions, such as might be used for instrumenting
+development code, or to produce variations aimed at a specific
+platform.
+
+The code below illustrates the way this can be done, and how the
+symbol replacement is performed.
+
+#+BEGIN_SRC js
+CLAUSE1: if (typeof DEVMODE === 'undefined') {
+ DEVMODE = true;
+}
+
+CLAUSE2: function init() {
+ if (DEVMODE) {
+ console.log("init() called");
+ }
+ ....
+ DEVMODE && console.log("init() complete");
+}
+
+CLAUSE3: function reportDeviceStatus(device) {
+ var DEVMODE = device.mode, DEVNAME = device.name;
+ if (DEVMODE === 'open') {
+ ....
+ }
+}
+#+END_SRC
+
+When the above code is normally executed, the undeclared global
+variable =DEVMODE= will be assigned the value *true* (see =CLAUSE1=)
+and so the =init()= function (=CLAUSE2=) will write messages to the
+console log when executed, but in =CLAUSE3= a locally declared
+variable will mask access to the =DEVMODE= global symbol.
+
+If the above code is processed by UglifyJS with an argument of
+=--define DEVMODE=false= then UglifyJS will replace =DEVMODE= with the
+boolean constant value *false* within =CLAUSE1= and =CLAUSE2=, but it
+will leave =CLAUSE3= as it stands because there =DEVMODE= resolves to
+a validly declared variable.
+
+And more so, the constant-folding features of UglifyJS will recognise
+that the =if= condition of =CLAUSE1= is thus always false, and so will
+remove the test and body of =CLAUSE1= altogether (including the
+otherwise slightly problematical statement =false = true;= which it
+will have formed by replacing =DEVMODE= in the body). Similarly,
+within =CLAUSE2= both calls to =console.log()= will be removed
+altogether.
+
+In this way you can mimic, to a limited degree, the functionality of
+the C/C++ pre-processor to enable or completely remove blocks
+depending on how certain symbols are defined - perhaps using UglifyJS
+to generate different versions of source aimed at different
+environments
+
+It is recommmended (but not made mandatory) that symbols designed for
+this purpose are given names consisting of =UPPER_CASE_LETTERS= to
+distinguish them from other (normal) symbols and avoid the sort of
+clash that =CLAUSE3= above illustrates.
+
+** Compression -- how good is it?
+
+Here are updated statistics. (I also updated my Google Closure and YUI
+installations).
+
+We're still a lot better than YUI in terms of compression, though slightly
+slower. We're still a lot faster than Closure, and compression after gzip
+is comparable.
+
+| File | UglifyJS | UglifyJS+gzip | Closure | Closure+gzip | YUI | YUI+gzip |
+|-----------------------------+------------------+---------------+------------------+--------------+------------------+----------|
+| jquery-1.6.2.js | 91001 (0:01.59) | 31896 | 90678 (0:07.40) | 31979 | 101527 (0:01.82) | 34646 |
+| paper.js | 142023 (0:01.65) | 43334 | 134301 (0:07.42) | 42495 | 173383 (0:01.58) | 48785 |
+| prototype.js | 88544 (0:01.09) | 26680 | 86955 (0:06.97) | 26326 | 92130 (0:00.79) | 28624 |
+| thelib-full.js (DynarchLIB) | 251939 (0:02.55) | 72535 | 249911 (0:09.05) | 72696 | 258869 (0:01.94) | 76584 |
+
+** Bugs?
+
+Unfortunately, for the time being there is no automated test suite. But I
+ran the compressor manually on non-trivial code, and then I tested that the
+generated code works as expected. A few hundred times.
+
+DynarchLIB was started in times when there was no good JS minifier.
+Therefore I was quite religious about trying to write short code manually,
+and as such DL contains a lot of syntactic hacks[1] such as “foo == bar ? a
+= 10 : b = 20”, though the more readable version would clearly be to use
+“if/else”.
+
+Since the parser/compressor runs fine on DL and jQuery, I'm quite confident
+that it's solid enough for production use. If you can identify any bugs,
+I'd love to hear about them ([[http://groups.google.com/group/uglifyjs][use the Google Group]] or email me directly).
+
+[1] I even reported a few bugs and suggested some fixes in the original
+ [[http://marijn.haverbeke.nl/parse-js/][parse-js]] library, and Marijn pushed fixes literally in minutes.
+
+** Links
+
+- Twitter: [[http://twitter.com/UglifyJS][@UglifyJS]]
+- Project at GitHub: [[http://github.com/mishoo/UglifyJS][http://github.com/mishoo/UglifyJS]]
+- Google Group: [[http://groups.google.com/group/uglifyjs][http://groups.google.com/group/uglifyjs]]
+- Common Lisp JS parser: [[http://marijn.haverbeke.nl/parse-js/][http://marijn.haverbeke.nl/parse-js/]]
+- JS-to-Lisp compiler: [[http://github.com/marijnh/js][http://github.com/marijnh/js]]
+- Common Lisp JS uglifier: [[http://github.com/mishoo/cl-uglify-js][http://github.com/mishoo/cl-uglify-js]]
+
+** License
+
+UglifyJS is released under the BSD license:
+
+#+BEGIN_EXAMPLE
+Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
+Based on parse-js (http://marijn.haverbeke.nl/parse-js/).
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+#+END_EXAMPLE
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjsbinuglifyjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/bin/uglifyjs (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/bin/uglifyjs (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/bin/uglifyjs 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,335 @@
</span><ins>+#!/usr/bin/env node
+// -*- js -*-
+
+global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util");
+var fs = require("fs"), path = require("path");
+var uglify = require("../uglify-js"), // symlink ~/.node_libraries/uglify-js.js to ../uglify-js.js
+ consolidator = uglify.consolidator,
+ jsp = uglify.parser,
+ pro = uglify.uglify;
+
+var options = {
+ ast: false,
+ consolidate: false,
+ mangle: true,
+ mangle_toplevel: false,
+ no_mangle_functions: false,
+ squeeze: true,
+ make_seqs: true,
+ dead_code: true,
+ verbose: false,
+ show_copyright: true,
+ out_same_file: false,
+ max_line_length: 32 * 1024,
+ unsafe: false,
+ reserved_names: null,
+ defines: { },
+ lift_vars: false,
+ codegen_options: {
+ ascii_only: false,
+ beautify: false,
+ indent_level: 4,
+ indent_start: 0,
+ quote_keys: false,
+ space_colon: false,
+ inline_script: false
+ },
+ make: false,
+ output: true // stdout
+};
+
+var args = jsp.slice(process.argv, 2);
+var filename;
+
+out: while (args.length > 0) {
+ var v = args.shift();
+ switch (v) {
+ case "-b":
+ case "--beautify":
+ options.codegen_options.beautify = true;
+ break;
+ case "-c":
+ case "--consolidate-primitive-values":
+ options.consolidate = true;
+ break;
+ case "-i":
+ case "--indent":
+ options.codegen_options.indent_level = args.shift();
+ break;
+ case "-q":
+ case "--quote-keys":
+ options.codegen_options.quote_keys = true;
+ break;
+ case "-mt":
+ case "--mangle-toplevel":
+ options.mangle_toplevel = true;
+ break;
+ case "-nmf":
+ case "--no-mangle-functions":
+ options.no_mangle_functions = true;
+ break;
+ case "--no-mangle":
+ case "-nm":
+ options.mangle = false;
+ break;
+ case "--no-squeeze":
+ case "-ns":
+ options.squeeze = false;
+ break;
+ case "--no-seqs":
+ options.make_seqs = false;
+ break;
+ case "--no-dead-code":
+ options.dead_code = false;
+ break;
+ case "--no-copyright":
+ case "-nc":
+ options.show_copyright = false;
+ break;
+ case "-o":
+ case "--output":
+ options.output = args.shift();
+ break;
+ case "--overwrite":
+ options.out_same_file = true;
+ break;
+ case "-v":
+ case "--verbose":
+ options.verbose = true;
+ break;
+ case "--ast":
+ options.ast = true;
+ break;
+ case "--unsafe":
+ options.unsafe = true;
+ break;
+ case "--max-line-len":
+ options.max_line_length = parseInt(args.shift(), 10);
+ break;
+ case "--reserved-names":
+ options.reserved_names = args.shift().split(",");
+ break;
+ case "--lift-vars":
+ options.lift_vars = true;
+ break;
+ case "-d":
+ case "--define":
+ var defarg = args.shift();
+ try {
+ var defsym = function(sym) {
+ // KEYWORDS_ATOM doesn't include NaN or Infinity - should we check
+ // for them too ?? We don't check reserved words and the like as the
+ // define values are only substituted AFTER parsing
+ if (jsp.KEYWORDS_ATOM.hasOwnProperty(sym)) {
+ throw "Don't define values for inbuilt constant '"+sym+"'";
+ }
+ return sym;
+ },
+ defval = function(v) {
+ if (v.match(/^"(.*)"$/) || v.match(/^'(.*)'$/)) {
+ return [ "string", RegExp.$1 ];
+ }
+ else if (!isNaN(parseFloat(v))) {
+ return [ "num", parseFloat(v) ];
+ }
+ else if (v.match(/^[a-z\$_][a-z\$_0-9]*$/i)) {
+ return [ "name", v ];
+ }
+ else if (!v.match(/"/)) {
+ return [ "string", v ];
+ }
+ else if (!v.match(/'/)) {
+ return [ "string", v ];
+ }
+ throw "Can't understand the specified value: "+v;
+ };
+ if (defarg.match(/^([a-z_\$][a-z_\$0-9]*)(=(.*))?$/i)) {
+ var sym = defsym(RegExp.$1),
+ val = RegExp.$2 ? defval(RegExp.$2.substr(1)) : [ 'name', 'true' ];
+ options.defines[sym] = val;
+ }
+ else {
+ throw "The --define option expects SYMBOL[=value]";
+ }
+ } catch(ex) {
+ sys.print("ERROR: In option --define "+defarg+"\n"+ex+"\n");
+ process.exit(1);
+ }
+ break;
+ case "--define-from-module":
+ var defmodarg = args.shift(),
+ defmodule = require(defmodarg),
+ sym,
+ val;
+ for (sym in defmodule) {
+ if (defmodule.hasOwnProperty(sym)) {
+ options.defines[sym] = function(val) {
+ if (typeof val == "string")
+ return [ "string", val ];
+ if (typeof val == "number")
+ return [ "num", val ];
+ if (val === true)
+ return [ 'name', 'true' ];
+ if (val === false)
+ return [ 'name', 'false' ];
+ if (val === null)
+ return [ 'name', 'null' ];
+ if (val === undefined)
+ return [ 'name', 'undefined' ];
+ sys.print("ERROR: In option --define-from-module "+defmodarg+"\n");
+ sys.print("ERROR: Unknown object type for: "+sym+"="+val+"\n");
+ process.exit(1);
+ return null;
+ }(defmodule[sym]);
+ }
+ }
+ break;
+ case "--ascii":
+ options.codegen_options.ascii_only = true;
+ break;
+ case "--make":
+ options.make = true;
+ break;
+ case "--inline-script":
+ options.codegen_options.inline_script = true;
+ break;
+ default:
+ filename = v;
+ break out;
+ }
+}
+
+if (options.verbose) {
+ pro.set_logger(function(msg){
+ sys.debug(msg);
+ });
+}
+
+jsp.set_logger(function(msg){
+ sys.debug(msg);
+});
+
+if (options.make) {
+ options.out_same_file = false; // doesn't make sense in this case
+ var makefile = global.eval("(" + fs.readFileSync(filename || "Makefile.uglify.js").toString() + ")");
+ var dir = path.dirname(filename);
+ output(makefile.files.map(function(file){
+ var code = fs.readFileSync(path.join(dir, file.name)).toString();
+ if (file.module) {
+ code = "!function(exports, global){global = this;\n" + code + "\n;this." + file.module + " = exports;}({})";
+ }
+ else if (file.hide) {
+ code = "(function(){" + code + "}());";
+ }
+ return squeeze_it(code);
+ }).join("\n"));
+}
+else if (filename) {
+ fs.readFile(filename, "utf8", function(err, text){
+ if (err) throw err;
+ output(squeeze_it(text));
+ });
+}
+else {
+ var stdin = process.openStdin();
+ stdin.setEncoding("utf8");
+ var text = "";
+ stdin.on("data", function(chunk){
+ text += chunk;
+ });
+ stdin.on("end", function() {
+ output(squeeze_it(text));
+ });
+}
+
+function output(text) {
+ var out;
+ if (options.out_same_file && filename)
+ options.output = filename;
+ if (options.output === true) {
+ out = process.stdout;
+ } else {
+ out = fs.createWriteStream(options.output, {
+ flags: "w",
+ encoding: "utf8",
+ mode: 0644
+ });
+ }
+ out.write(text.replace(/;*$/, ";"));
+ if (options.output !== true) {
+ out.end();
+ }
+};
+
+// --------- main ends here.
+
+function show_copyright(comments) {
+ var ret = "";
+ for (var i = 0; i < comments.length; ++i) {
+ var c = comments[i];
+ if (c.type == "comment1") {
+ ret += "//" + c.value + "\n";
+ } else {
+ ret += "/*" + c.value + "*/";
+ }
+ }
+ return ret;
+};
+
+function squeeze_it(code) {
+ var result = "";
+ if (options.show_copyright) {
+ var tok = jsp.tokenizer(code), c;
+ c = tok();
+ result += show_copyright(c.comments_before);
+ }
+ try {
+ var ast = time_it("parse", function(){ return jsp.parse(code); });
+ if (options.consolidate) ast = time_it("consolidate", function(){
+ return consolidator.ast_consolidate(ast);
+ });
+ if (options.lift_vars) {
+ ast = time_it("lift", function(){ return pro.ast_lift_variables(ast); });
+ }
+ ast = time_it("mangle", function(){
+ return pro.ast_mangle(ast, {
+ mangle : options.mangle,
+ toplevel : options.mangle_toplevel,
+ defines : options.defines,
+ except : options.reserved_names,
+ no_functions : options.no_mangle_functions
+ });
+ });
+ if (options.squeeze) ast = time_it("squeeze", function(){
+ ast = pro.ast_squeeze(ast, {
+ make_seqs : options.make_seqs,
+ dead_code : options.dead_code,
+ keep_comps : !options.unsafe,
+ unsafe : options.unsafe
+ });
+ if (options.unsafe)
+ ast = pro.ast_squeeze_more(ast);
+ return ast;
+ });
+ if (options.ast)
+ return sys.inspect(ast, null, null);
+ result += time_it("generate", function(){ return pro.gen_code(ast, options.codegen_options) });
+ if (!options.codegen_options.beautify && options.max_line_length) {
+ result = time_it("split", function(){ return pro.split_lines(result, options.max_line_length) });
+ }
+ return result;
+ } catch(ex) {
+ sys.debug(ex.stack);
+ sys.debug(sys.inspect(ex));
+ sys.debug(JSON.stringify(ex));
+ process.exit(1);
+ }
+};
+
+function time_it(name, cont) {
+ if (!options.verbose)
+ return cont();
+ var t1 = new Date().getTime();
+ try { return cont(); }
+ finally { sys.debug("// " + name + ": " + ((new Date().getTime() - t1) / 1000).toFixed(3) + " sec."); }
+};
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/bin/uglifyjs
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjsdocstylecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/docstyle.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/docstyle.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/docstyle.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,75 @@
</span><ins>+html { font-family: "Lucida Grande","Trebuchet MS",sans-serif; font-size: 12pt; }
+body { max-width: 60em; }
+.title { text-align: center; }
+.todo { color: red; }
+.done { color: green; }
+.tag { background-color:lightblue; font-weight:normal }
+.target { }
+.timestamp { color: grey }
+.timestamp-kwd { color: CadetBlue }
+p.verse { margin-left: 3% }
+pre {
+ border: 1pt solid #AEBDCC;
+ background-color: #F3F5F7;
+ padding: 5pt;
+ font-family: monospace;
+ font-size: 90%;
+ overflow:auto;
+}
+pre.src {
+ background-color: #eee; color: #112; border: 1px solid #000;
+}
+table { border-collapse: collapse; }
+td, th { vertical-align: top; }
+dt { font-weight: bold; }
+div.figure { padding: 0.5em; }
+div.figure p { text-align: center; }
+.linenr { font-size:smaller }
+.code-highlighted {background-color:#ffff00;}
+.org-info-js_info-navigation { border-style:none; }
+#org-info-js_console-label { font-size:10px; font-weight:bold;
+ white-space:nowrap; }
+.org-info-js_search-highlight {background-color:#ffff00; color:#000000;
+ font-weight:bold; }
+
+sup {
+ vertical-align: baseline;
+ position: relative;
+ top: -0.5em;
+ font-size: 80%;
+}
+
+sup a:link, sup a:visited {
+ text-decoration: none;
+ color: #c00;
+}
+
+sup a:before { content: "["; color: #999; }
+sup a:after { content: "]"; color: #999; }
+
+h1.title { border-bottom: 4px solid #000; padding-bottom: 5px; margin-bottom: 2em; }
+
+#postamble {
+ color: #777;
+ font-size: 90%;
+ padding-top: 1em; padding-bottom: 1em; border-top: 1px solid #999;
+ margin-top: 2em;
+ padding-left: 2em;
+ padding-right: 2em;
+ text-align: right;
+}
+
+#postamble p { margin: 0; }
+
+#footnotes { border-top: 1px solid #000; }
+
+h1 { font-size: 200% }
+h2 { font-size: 175% }
+h3 { font-size: 150% }
+h4 { font-size: 125% }
+
+h1, h2, h3, h4 { font-family: "Bookman",Georgia,"Times New Roman",serif; font-weight: normal; }
+
+@media print {
+ html { font-size: 11pt; }
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjslibconsolidatorjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/consolidator.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/consolidator.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/consolidator.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,1220 @@
</span><ins>+/**
+ * @preserve Copyright 2012 Robert Gust-Bardon <http://robert.gust-bardon.org/>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/**
+ * @fileoverview Enhances <a href="https://github.com/mishoo/UglifyJS/"
+ * >UglifyJS</a> with consolidation of null, Boolean, and String values.
+ * <p>Also known as aliasing, this feature has been deprecated in <a href=
+ * "http://closure-compiler.googlecode.com/">the Closure Compiler</a> since its
+ * initial release, where it is unavailable from the <abbr title=
+ * "command line interface">CLI</a>. The Closure Compiler allows one to log and
+ * influence this process. In contrast, this implementation does not introduce
+ * any variable declarations in global code and derives String values from
+ * identifier names used as property accessors.</p>
+ * <p>Consolidating literals may worsen the data compression ratio when an <a
+ * href="http://tools.ietf.org/html/rfc2616#section-3.5">encoding
+ * transformation</a> is applied. For instance, <a href=
+ * "http://code.jquery.com/jquery-1.7.1.js">jQuery 1.7.1</a> takes 248235 bytes.
+ * Building it with <a href="https://github.com/mishoo/UglifyJS/tarball/v1.2.5">
+ * UglifyJS v1.2.5</a> results in 93647 bytes (37.73% of the original) which are
+ * then compressed to 33154 bytes (13.36% of the original) using <a href=
+ * "http://linux.die.net/man/1/gzip">gzip(1)</a>. Building it with the same
+ * version of UglifyJS 1.2.5 patched with the implementation of consolidation
+ * results in 80784 bytes (a decrease of 12863 bytes, i.e. 13.74%, in comparison
+ * to the aforementioned 93647 bytes) which are then compressed to 34013 bytes
+ * (an increase of 859 bytes, i.e. 2.59%, in comparison to the aforementioned
+ * 33154 bytes).</p>
+ * <p>Written in <a href="http://es5.github.com/#x4.2.2">the strict variant</a>
+ * of <a href="http://es5.github.com/">ECMA-262 5.1 Edition</a>. Encoded in <a
+ * href="http://tools.ietf.org/html/rfc3629">UTF-8</a>. Follows <a href=
+ * "http://google-styleguide.googlecode.com/svn-history/r76/trunk/javascriptguide.xml"
+ * >Revision 2.28 of the Google JavaScript Style Guide</a> (except for the
+ * discouraged use of the {@code function} tag and the {@code namespace} tag).
+ * 100% typed for the <a href=
+ * "http://closure-compiler.googlecode.com/files/compiler-20120123.tar.gz"
+ * >Closure Compiler Version 1741</a>.</p>
+ * <p>Should you find this software useful, please consider <a href=
+ * "https://paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=JZLW72X8FD4WG"
+ * >a donation</a>.</p>
+ * @author follow.me@RGustBardon (Robert Gust-Bardon)
+ * @supported Tested with:
+ * <ul>
+ * <li><a href="http://nodejs.org/dist/v0.6.10/">Node v0.6.10</a>,</li>
+ * <li><a href="https://github.com/mishoo/UglifyJS/tarball/v1.2.5">UglifyJS
+ * v1.2.5</a>.</li>
+ * </ul>
+ */
+
+/*global console:false, exports:true, module:false, require:false */
+/*jshint sub:true */
+/**
+ * Consolidates null, Boolean, and String values found inside an <abbr title=
+ * "abstract syntax tree">AST</abbr>.
+ * @param {!TSyntacticCodeUnit} oAbstractSyntaxTree An array-like object
+ * representing an <abbr title="abstract syntax tree">AST</abbr>.
+ * @return {!TSyntacticCodeUnit} An array-like object representing an <abbr
+ * title="abstract syntax tree">AST</abbr> with its null, Boolean, and
+ * String values consolidated.
+ */
+// TODO(user) Consolidation of mathematical values found in numeric literals.
+// TODO(user) Unconsolidation.
+// TODO(user) Consolidation of ECMA-262 6th Edition programs.
+// TODO(user) Rewrite in ECMA-262 6th Edition.
+exports['ast_consolidate'] = function(oAbstractSyntaxTree) {
+ 'use strict';
+ /*jshint bitwise:true, curly:true, eqeqeq:true, forin:true, immed:true,
+ latedef:true, newcap:true, noarge:true, noempty:true, nonew:true,
+ onevar:true, plusplus:true, regexp:true, undef:true, strict:true,
+ sub:false, trailing:true */
+
+ var _,
+ /**
+ * A record consisting of data about one or more source elements.
+ * @constructor
+ * @nosideeffects
+ */
+ TSourceElementsData = function() {
+ /**
+ * The category of the elements.
+ * @type {number}
+ * @see ESourceElementCategories
+ */
+ this.nCategory = ESourceElementCategories.N_OTHER;
+ /**
+ * The number of occurrences (within the elements) of each primitive
+ * value that could be consolidated.
+ * @type {!Array.<!Object.<string, number>>}
+ */
+ this.aCount = [];
+ this.aCount[EPrimaryExpressionCategories.N_IDENTIFIER_NAMES] = {};
+ this.aCount[EPrimaryExpressionCategories.N_STRING_LITERALS] = {};
+ this.aCount[EPrimaryExpressionCategories.N_NULL_AND_BOOLEAN_LITERALS] =
+ {};
+ /**
+ * Identifier names found within the elements.
+ * @type {!Array.<string>}
+ */
+ this.aIdentifiers = [];
+ /**
+ * Prefixed representation Strings of each primitive value that could be
+ * consolidated within the elements.
+ * @type {!Array.<string>}
+ */
+ this.aPrimitiveValues = [];
+ },
+ /**
+ * A record consisting of data about a primitive value that could be
+ * consolidated.
+ * @constructor
+ * @nosideeffects
+ */
+ TPrimitiveValue = function() {
+ /**
+ * The difference in the number of terminal symbols between the original
+ * source text and the one with the primitive value consolidated. If the
+ * difference is positive, the primitive value is considered worthwhile.
+ * @type {number}
+ */
+ this.nSaving = 0;
+ /**
+ * An identifier name of the variable that will be declared and assigned
+ * the primitive value if the primitive value is consolidated.
+ * @type {string}
+ */
+ this.sName = '';
+ },
+ /**
+ * A record consisting of data on what to consolidate within the range of
+ * source elements that is currently being considered.
+ * @constructor
+ * @nosideeffects
+ */
+ TSolution = function() {
+ /**
+ * An object whose keys are prefixed representation Strings of each
+ * primitive value that could be consolidated within the elements and
+ * whose values are corresponding data about those primitive values.
+ * @type {!Object.<string, {nSaving: number, sName: string}>}
+ * @see TPrimitiveValue
+ */
+ this.oPrimitiveValues = {};
+ /**
+ * The difference in the number of terminal symbols between the original
+ * source text and the one with all the worthwhile primitive values
+ * consolidated.
+ * @type {number}
+ * @see TPrimitiveValue#nSaving
+ */
+ this.nSavings = 0;
+ },
+ /**
+ * The processor of <abbr title="abstract syntax tree">AST</abbr>s found
+ * in UglifyJS.
+ * @namespace
+ * @type {!TProcessor}
+ */
+ oProcessor = (/** @type {!TProcessor} */ require('./process')),
+ /**
+ * A record consisting of a number of constants that represent the
+ * difference in the number of terminal symbols between a source text with
+ * a modified syntactic code unit and the original one.
+ * @namespace
+ * @type {!Object.<string, number>}
+ */
+ oWeights = {
+ /**
+ * The difference in the number of punctuators required by the bracket
+ * notation and the dot notation.
+ * <p><code>'[]'.length - '.'.length</code></p>
+ * @const
+ * @type {number}
+ */
+ N_PROPERTY_ACCESSOR: 1,
+ /**
+ * The number of punctuators required by a variable declaration with an
+ * initialiser.
+ * <p><code>':'.length + ';'.length</code></p>
+ * @const
+ * @type {number}
+ */
+ N_VARIABLE_DECLARATION: 2,
+ /**
+ * The number of terminal symbols required to introduce a variable
+ * statement (excluding its variable declaration list).
+ * <p><code>'var '.length</code></p>
+ * @const
+ * @type {number}
+ */
+ N_VARIABLE_STATEMENT_AFFIXATION: 4,
+ /**
+ * The number of terminal symbols needed to enclose source elements
+ * within a function call with no argument values to a function with an
+ * empty parameter list.
+ * <p><code>'(function(){}());'.length</code></p>
+ * @const
+ * @type {number}
+ */
+ N_CLOSURE: 17
+ },
+ /**
+ * Categories of primary expressions from which primitive values that
+ * could be consolidated are derivable.
+ * @namespace
+ * @enum {number}
+ */
+ EPrimaryExpressionCategories = {
+ /**
+ * Identifier names used as property accessors.
+ * @type {number}
+ */
+ N_IDENTIFIER_NAMES: 0,
+ /**
+ * String literals.
+ * @type {number}
+ */
+ N_STRING_LITERALS: 1,
+ /**
+ * Null and Boolean literals.
+ * @type {number}
+ */
+ N_NULL_AND_BOOLEAN_LITERALS: 2
+ },
+ /**
+ * Prefixes of primitive values that could be consolidated.
+ * The String values of the prefixes must have same number of characters.
+ * The prefixes must not be used in any properties defined in any version
+ * of <a href=
+ * "http://www.ecma-international.org/publications/standards/Ecma-262.htm"
+ * >ECMA-262</a>.
+ * @namespace
+ * @enum {string}
+ */
+ EValuePrefixes = {
+ /**
+ * Identifies String values.
+ * @type {string}
+ */
+ S_STRING: '#S',
+ /**
+ * Identifies null and Boolean values.
+ * @type {string}
+ */
+ S_SYMBOLIC: '#O'
+ },
+ /**
+ * Categories of source elements in terms of their appropriateness of
+ * having their primitive values consolidated.
+ * @namespace
+ * @enum {number}
+ */
+ ESourceElementCategories = {
+ /**
+ * Identifies a source element that includes the <a href=
+ * "http://es5.github.com/#x12.10">{@code with}</a> statement.
+ * @type {number}
+ */
+ N_WITH: 0,
+ /**
+ * Identifies a source element that includes the <a href=
+ * "http://es5.github.com/#x15.1.2.1">{@code eval}</a> identifier name.
+ * @type {number}
+ */
+ N_EVAL: 1,
+ /**
+ * Identifies a source element that must be excluded from the process
+ * unless its whole scope is examined.
+ * @type {number}
+ */
+ N_EXCLUDABLE: 2,
+ /**
+ * Identifies source elements not posing any problems.
+ * @type {number}
+ */
+ N_OTHER: 3
+ },
+ /**
+ * The list of literals (other than the String ones) whose primitive
+ * values can be consolidated.
+ * @const
+ * @type {!Array.<string>}
+ */
+ A_OTHER_SUBSTITUTABLE_LITERALS = [
+ 'null', // The null literal.
+ 'false', // The Boolean literal {@code false}.
+ 'true' // The Boolean literal {@code true}.
+ ];
+
+ (/**
+ * Consolidates all worthwhile primitive values in a syntactic code unit.
+ * @param {!TSyntacticCodeUnit} oSyntacticCodeUnit An array-like object
+ * representing the branch of the abstract syntax tree representing the
+ * syntactic code unit along with its scope.
+ * @see TPrimitiveValue#nSaving
+ */
+ function fExamineSyntacticCodeUnit(oSyntacticCodeUnit) {
+ var _,
+ /**
+ * Indicates whether the syntactic code unit represents global code.
+ * @type {boolean}
+ */
+ bIsGlobal = 'toplevel' === oSyntacticCodeUnit[0],
+ /**
+ * Indicates whether the whole scope is being examined.
+ * @type {boolean}
+ */
+ bIsWhollyExaminable = !bIsGlobal,
+ /**
+ * An array-like object representing source elements that constitute a
+ * syntactic code unit.
+ * @type {!TSyntacticCodeUnit}
+ */
+ oSourceElements,
+ /**
+ * A record consisting of data about the source element that is
+ * currently being examined.
+ * @type {!TSourceElementsData}
+ */
+ oSourceElementData,
+ /**
+ * The scope of the syntactic code unit.
+ * @type {!TScope}
+ */
+ oScope,
+ /**
+ * An instance of an object that allows the traversal of an <abbr
+ * title="abstract syntax tree">AST</abbr>.
+ * @type {!TWalker}
+ */
+ oWalker,
+ /**
+ * An object encompassing collections of functions used during the
+ * traversal of an <abbr title="abstract syntax tree">AST</abbr>.
+ * @namespace
+ * @type {!Object.<string, !Object.<string, function(...[*])>>}
+ */
+ oWalkers = {
+ /**
+ * A collection of functions used during the surveyance of source
+ * elements.
+ * @namespace
+ * @type {!Object.<string, function(...[*])>}
+ */
+ oSurveySourceElement: {
+ /**#nocode+*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
+ /**
+ * Classifies the source element as excludable if it does not
+ * contain a {@code with} statement or the {@code eval} identifier
+ * name. Adds the identifier of the function and its formal
+ * parameters to the list of identifier names found.
+ * @param {string} sIdentifier The identifier of the function.
+ * @param {!Array.<string>} aFormalParameterList Formal parameters.
+ * @param {!TSyntacticCodeUnit} oFunctionBody Function code.
+ */
+ 'defun': function(
+ sIdentifier,
+ aFormalParameterList,
+ oFunctionBody) {
+ fClassifyAsExcludable();
+ fAddIdentifier(sIdentifier);
+ aFormalParameterList.forEach(fAddIdentifier);
+ },
+ /**
+ * Increments the count of the number of occurrences of the String
+ * value that is equivalent to the sequence of terminal symbols
+ * that constitute the encountered identifier name.
+ * @param {!TSyntacticCodeUnit} oExpression The nonterminal
+ * MemberExpression.
+ * @param {string} sIdentifierName The identifier name used as the
+ * property accessor.
+ * @return {!Array} The encountered branch of an <abbr title=
+ * "abstract syntax tree">AST</abbr> with its nonterminal
+ * MemberExpression traversed.
+ */
+ 'dot': function(oExpression, sIdentifierName) {
+ fCountPrimaryExpression(
+ EPrimaryExpressionCategories.N_IDENTIFIER_NAMES,
+ EValuePrefixes.S_STRING + sIdentifierName);
+ return ['dot', oWalker.walk(oExpression), sIdentifierName];
+ },
+ /**
+ * Adds the optional identifier of the function and its formal
+ * parameters to the list of identifier names found.
+ * @param {?string} sIdentifier The optional identifier of the
+ * function.
+ * @param {!Array.<string>} aFormalParameterList Formal parameters.
+ * @param {!TSyntacticCodeUnit} oFunctionBody Function code.
+ */
+ 'function': function(
+ sIdentifier,
+ aFormalParameterList,
+ oFunctionBody) {
+ if ('string' === typeof sIdentifier) {
+ fAddIdentifier(sIdentifier);
+ }
+ aFormalParameterList.forEach(fAddIdentifier);
+ },
+ /**
+ * Either increments the count of the number of occurrences of the
+ * encountered null or Boolean value or classifies a source element
+ * as containing the {@code eval} identifier name.
+ * @param {string} sIdentifier The identifier encountered.
+ */
+ 'name': function(sIdentifier) {
+ if (-1 !== A_OTHER_SUBSTITUTABLE_LITERALS.indexOf(sIdentifier)) {
+ fCountPrimaryExpression(
+ EPrimaryExpressionCategories.N_NULL_AND_BOOLEAN_LITERALS,
+ EValuePrefixes.S_SYMBOLIC + sIdentifier);
+ } else {
+ if ('eval' === sIdentifier) {
+ oSourceElementData.nCategory =
+ ESourceElementCategories.N_EVAL;
+ }
+ fAddIdentifier(sIdentifier);
+ }
+ },
+ /**
+ * Classifies the source element as excludable if it does not
+ * contain a {@code with} statement or the {@code eval} identifier
+ * name.
+ * @param {TSyntacticCodeUnit} oExpression The expression whose
+ * value is to be returned.
+ */
+ 'return': function(oExpression) {
+ fClassifyAsExcludable();
+ },
+ /**
+ * Increments the count of the number of occurrences of the
+ * encountered String value.
+ * @param {string} sStringValue The String value of the string
+ * literal encountered.
+ */
+ 'string': function(sStringValue) {
+ if (sStringValue.length > 0) {
+ fCountPrimaryExpression(
+ EPrimaryExpressionCategories.N_STRING_LITERALS,
+ EValuePrefixes.S_STRING + sStringValue);
+ }
+ },
+ /**
+ * Adds the identifier reserved for an exception to the list of
+ * identifier names found.
+ * @param {!TSyntacticCodeUnit} oTry A block of code in which an
+ * exception can occur.
+ * @param {Array} aCatch The identifier reserved for an exception
+ * and a block of code to handle the exception.
+ * @param {TSyntacticCodeUnit} oFinally An optional block of code
+ * to be evaluated regardless of whether an exception occurs.
+ */
+ 'try': function(oTry, aCatch, oFinally) {
+ if (Array.isArray(aCatch)) {
+ fAddIdentifier(aCatch[0]);
+ }
+ },
+ /**
+ * Classifies the source element as excludable if it does not
+ * contain a {@code with} statement or the {@code eval} identifier
+ * name. Adds the identifier of each declared variable to the list
+ * of identifier names found.
+ * @param {!Array.<!Array>} aVariableDeclarationList Variable
+ * declarations.
+ */
+ 'var': function(aVariableDeclarationList) {
+ fClassifyAsExcludable();
+ aVariableDeclarationList.forEach(fAddVariable);
+ },
+ /**
+ * Classifies a source element as containing the {@code with}
+ * statement.
+ * @param {!TSyntacticCodeUnit} oExpression An expression whose
+ * value is to be converted to a value of type Object and
+ * become the binding object of a new object environment
+ * record of a new lexical environment in which the statement
+ * is to be executed.
+ * @param {!TSyntacticCodeUnit} oStatement The statement to be
+ * executed in the augmented lexical environment.
+ * @return {!Array} An empty array to stop the traversal.
+ */
+ 'with': function(oExpression, oStatement) {
+ oSourceElementData.nCategory = ESourceElementCategories.N_WITH;
+ return [];
+ }
+ /**#nocode-*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
+ },
+ /**
+ * A collection of functions used while looking for nested functions.
+ * @namespace
+ * @type {!Object.<string, function(...[*])>}
+ */
+ oExamineFunctions: {
+ /**#nocode+*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
+ /**
+ * Orders an examination of a nested function declaration.
+ * @this {!TSyntacticCodeUnit} An array-like object representing
+ * the branch of an <abbr title="abstract syntax tree"
+ * >AST</abbr> representing the syntactic code unit along with
+ * its scope.
+ * @return {!Array} An empty array to stop the traversal.
+ */
+ 'defun': function() {
+ fExamineSyntacticCodeUnit(this);
+ return [];
+ },
+ /**
+ * Orders an examination of a nested function expression.
+ * @this {!TSyntacticCodeUnit} An array-like object representing
+ * the branch of an <abbr title="abstract syntax tree"
+ * >AST</abbr> representing the syntactic code unit along with
+ * its scope.
+ * @return {!Array} An empty array to stop the traversal.
+ */
+ 'function': function() {
+ fExamineSyntacticCodeUnit(this);
+ return [];
+ }
+ /**#nocode-*/ // JsDoc Toolkit 2.4.0 hides some of the keys.
+ }
+ },
+ /**
+ * Records containing data about source elements.
+ * @type {Array.<TSourceElementsData>}
+ */
+ aSourceElementsData = [],
+ /**
+ * The index (in the source text order) of the source element
+ * immediately following a <a href="http://es5.github.com/#x14.1"
+ * >Directive Prologue</a>.
+ * @type {number}
+ */
+ nAfterDirectivePrologue = 0,
+ /**
+ * The index (in the source text order) of the source element that is
+ * currently being considered.
+ * @type {number}
+ */
+ nPosition,
+ /**
+ * The index (in the source text order) of the source element that is
+ * the last element of the range of source elements that is currently
+ * being considered.
+ * @type {(undefined|number)}
+ */
+ nTo,
+ /**
+ * Initiates the traversal of a source element.
+ * @param {!TWalker} oWalker An instance of an object that allows the
+ * traversal of an abstract syntax tree.
+ * @param {!TSyntacticCodeUnit} oSourceElement A source element from
+ * which the traversal should commence.
+ * @return {function(): !TSyntacticCodeUnit} A function that is able to
+ * initiate the traversal from a given source element.
+ */
+ cContext = function(oWalker, oSourceElement) {
+ /**
+ * @return {!TSyntacticCodeUnit} A function that is able to
+ * initiate the traversal from a given source element.
+ */
+ var fLambda = function() {
+ return oWalker.walk(oSourceElement);
+ };
+
+ return fLambda;
+ },
+ /**
+ * Classifies the source element as excludable if it does not
+ * contain a {@code with} statement or the {@code eval} identifier
+ * name.
+ */
+ fClassifyAsExcludable = function() {
+ if (oSourceElementData.nCategory ===
+ ESourceElementCategories.N_OTHER) {
+ oSourceElementData.nCategory =
+ ESourceElementCategories.N_EXCLUDABLE;
+ }
+ },
+ /**
+ * Adds an identifier to the list of identifier names found.
+ * @param {string} sIdentifier The identifier to be added.
+ */
+ fAddIdentifier = function(sIdentifier) {
+ if (-1 === oSourceElementData.aIdentifiers.indexOf(sIdentifier)) {
+ oSourceElementData.aIdentifiers.push(sIdentifier);
+ }
+ },
+ /**
+ * Adds the identifier of a variable to the list of identifier names
+ * found.
+ * @param {!Array} aVariableDeclaration A variable declaration.
+ */
+ fAddVariable = function(aVariableDeclaration) {
+ fAddIdentifier(/** @type {string} */ aVariableDeclaration[0]);
+ },
+ /**
+ * Increments the count of the number of occurrences of the prefixed
+ * String representation attributed to the primary expression.
+ * @param {number} nCategory The category of the primary expression.
+ * @param {string} sName The prefixed String representation attributed
+ * to the primary expression.
+ */
+ fCountPrimaryExpression = function(nCategory, sName) {
+ if (!oSourceElementData.aCount[nCategory].hasOwnProperty(sName)) {
+ oSourceElementData.aCount[nCategory][sName] = 0;
+ if (-1 === oSourceElementData.aPrimitiveValues.indexOf(sName)) {
+ oSourceElementData.aPrimitiveValues.push(sName);
+ }
+ }
+ oSourceElementData.aCount[nCategory][sName] += 1;
+ },
+ /**
+ * Consolidates all worthwhile primitive values in a range of source
+ * elements.
+ * @param {number} nFrom The index (in the source text order) of the
+ * source element that is the first element of the range.
+ * @param {number} nTo The index (in the source text order) of the
+ * source element that is the last element of the range.
+ * @param {boolean} bEnclose Indicates whether the range should be
+ * enclosed within a function call with no argument values to a
+ * function with an empty parameter list if any primitive values
+ * are consolidated.
+ * @see TPrimitiveValue#nSaving
+ */
+ fExamineSourceElements = function(nFrom, nTo, bEnclose) {
+ var _,
+ /**
+ * The index of the last mangled name.
+ * @type {number}
+ */
+ nIndex = oScope.cname,
+ /**
+ * The index of the source element that is currently being
+ * considered.
+ * @type {number}
+ */
+ nPosition,
+ /**
+ * A collection of functions used during the consolidation of
+ * primitive values and identifier names used as property
+ * accessors.
+ * @namespace
+ * @type {!Object.<string, function(...[*])>}
+ */
+ oWalkersTransformers = {
+ /**
+ * If the String value that is equivalent to the sequence of
+ * terminal symbols that constitute the encountered identifier
+ * name is worthwhile, a syntactic conversion from the dot
+ * notation to the bracket notation ensues with that sequence
+ * being substituted by an identifier name to which the value
+ * is assigned.
+ * Applies to property accessors that use the dot notation.
+ * @param {!TSyntacticCodeUnit} oExpression The nonterminal
+ * MemberExpression.
+ * @param {string} sIdentifierName The identifier name used as
+ * the property accessor.
+ * @return {!Array} A syntactic code unit that is equivalent to
+ * the one encountered.
+ * @see TPrimitiveValue#nSaving
+ */
+ 'dot': function(oExpression, sIdentifierName) {
+ /**
+ * The prefixed String value that is equivalent to the
+ * sequence of terminal symbols that constitute the
+ * encountered identifier name.
+ * @type {string}
+ */
+ var sPrefixed = EValuePrefixes.S_STRING + sIdentifierName;
+
+ return oSolutionBest.oPrimitiveValues.hasOwnProperty(
+ sPrefixed) &&
+ oSolutionBest.oPrimitiveValues[sPrefixed].nSaving > 0 ?
+ ['sub',
+ oWalker.walk(oExpression),
+ ['name',
+ oSolutionBest.oPrimitiveValues[sPrefixed].sName]] :
+ ['dot', oWalker.walk(oExpression), sIdentifierName];
+ },
+ /**
+ * If the encountered identifier is a null or Boolean literal
+ * and its value is worthwhile, the identifier is substituted
+ * by an identifier name to which that value is assigned.
+ * Applies to identifier names.
+ * @param {string} sIdentifier The identifier encountered.
+ * @return {!Array} A syntactic code unit that is equivalent to
+ * the one encountered.
+ * @see TPrimitiveValue#nSaving
+ */
+ 'name': function(sIdentifier) {
+ /**
+ * The prefixed representation String of the identifier.
+ * @type {string}
+ */
+ var sPrefixed = EValuePrefixes.S_SYMBOLIC + sIdentifier;
+
+ return [
+ 'name',
+ oSolutionBest.oPrimitiveValues.hasOwnProperty(sPrefixed) &&
+ oSolutionBest.oPrimitiveValues[sPrefixed].nSaving > 0 ?
+ oSolutionBest.oPrimitiveValues[sPrefixed].sName :
+ sIdentifier
+ ];
+ },
+ /**
+ * If the encountered String value is worthwhile, it is
+ * substituted by an identifier name to which that value is
+ * assigned.
+ * Applies to String values.
+ * @param {string} sStringValue The String value of the string
+ * literal encountered.
+ * @return {!Array} A syntactic code unit that is equivalent to
+ * the one encountered.
+ * @see TPrimitiveValue#nSaving
+ */
+ 'string': function(sStringValue) {
+ /**
+ * The prefixed representation String of the primitive value
+ * of the literal.
+ * @type {string}
+ */
+ var sPrefixed =
+ EValuePrefixes.S_STRING + sStringValue;
+
+ return oSolutionBest.oPrimitiveValues.hasOwnProperty(
+ sPrefixed) &&
+ oSolutionBest.oPrimitiveValues[sPrefixed].nSaving > 0 ?
+ ['name',
+ oSolutionBest.oPrimitiveValues[sPrefixed].sName] :
+ ['string', sStringValue];
+ }
+ },
+ /**
+ * Such data on what to consolidate within the range of source
+ * elements that is currently being considered that lead to the
+ * greatest known reduction of the number of the terminal symbols
+ * in comparison to the original source text.
+ * @type {!TSolution}
+ */
+ oSolutionBest = new TSolution(),
+ /**
+ * Data representing an ongoing attempt to find a better
+ * reduction of the number of the terminal symbols in comparison
+ * to the original source text than the best one that is
+ * currently known.
+ * @type {!TSolution}
+ * @see oSolutionBest
+ */
+ oSolutionCandidate = new TSolution(),
+ /**
+ * A record consisting of data about the range of source elements
+ * that is currently being examined.
+ * @type {!TSourceElementsData}
+ */
+ oSourceElementsData = new TSourceElementsData(),
+ /**
+ * Variable declarations for each primitive value that is to be
+ * consolidated within the elements.
+ * @type {!Array.<!Array>}
+ */
+ aVariableDeclarations = [],
+ /**
+ * Augments a list with a prefixed representation String.
+ * @param {!Array.<string>} aList A list that is to be augmented.
+ * @return {function(string)} A function that augments a list
+ * with a prefixed representation String.
+ */
+ cAugmentList = function(aList) {
+ /**
+ * @param {string} sPrefixed Prefixed representation String of
+ * a primitive value that could be consolidated within the
+ * elements.
+ */
+ var fLambda = function(sPrefixed) {
+ if (-1 === aList.indexOf(sPrefixed)) {
+ aList.push(sPrefixed);
+ }
+ };
+
+ return fLambda;
+ },
+ /**
+ * Adds the number of occurrences of a primitive value of a given
+ * category that could be consolidated in the source element with
+ * a given index to the count of occurrences of that primitive
+ * value within the range of source elements that is currently
+ * being considered.
+ * @param {number} nPosition The index (in the source text order)
+ * of a source element.
+ * @param {number} nCategory The category of the primary
+ * expression from which the primitive value is derived.
+ * @return {function(string)} A function that performs the
+ * addition.
+ * @see cAddOccurrencesInCategory
+ */
+ cAddOccurrences = function(nPosition, nCategory) {
+ /**
+ * @param {string} sPrefixed The prefixed representation String
+ * of a primitive value.
+ */
+ var fLambda = function(sPrefixed) {
+ if (!oSourceElementsData.aCount[nCategory].hasOwnProperty(
+ sPrefixed)) {
+ oSourceElementsData.aCount[nCategory][sPrefixed] = 0;
+ }
+ oSourceElementsData.aCount[nCategory][sPrefixed] +=
+ aSourceElementsData[nPosition].aCount[nCategory][
+ sPrefixed];
+ };
+
+ return fLambda;
+ },
+ /**
+ * Adds the number of occurrences of each primitive value of a
+ * given category that could be consolidated in the source
+ * element with a given index to the count of occurrences of that
+ * primitive values within the range of source elements that is
+ * currently being considered.
+ * @param {number} nPosition The index (in the source text order)
+ * of a source element.
+ * @return {function(number)} A function that performs the
+ * addition.
+ * @see fAddOccurrences
+ */
+ cAddOccurrencesInCategory = function(nPosition) {
+ /**
+ * @param {number} nCategory The category of the primary
+ * expression from which the primitive value is derived.
+ */
+ var fLambda = function(nCategory) {
+ Object.keys(
+ aSourceElementsData[nPosition].aCount[nCategory]
+ ).forEach(cAddOccurrences(nPosition, nCategory));
+ };
+
+ return fLambda;
+ },
+ /**
+ * Adds the number of occurrences of each primitive value that
+ * could be consolidated in the source element with a given index
+ * to the count of occurrences of that primitive values within
+ * the range of source elements that is currently being
+ * considered.
+ * @param {number} nPosition The index (in the source text order)
+ * of a source element.
+ */
+ fAddOccurrences = function(nPosition) {
+ Object.keys(aSourceElementsData[nPosition].aCount).forEach(
+ cAddOccurrencesInCategory(nPosition));
+ },
+ /**
+ * Creates a variable declaration for a primitive value if that
+ * primitive value is to be consolidated within the elements.
+ * @param {string} sPrefixed Prefixed representation String of a
+ * primitive value that could be consolidated within the
+ * elements.
+ * @see aVariableDeclarations
+ */
+ cAugmentVariableDeclarations = function(sPrefixed) {
+ if (oSolutionBest.oPrimitiveValues[sPrefixed].nSaving > 0) {
+ aVariableDeclarations.push([
+ oSolutionBest.oPrimitiveValues[sPrefixed].sName,
+ [0 === sPrefixed.indexOf(EValuePrefixes.S_SYMBOLIC) ?
+ 'name' : 'string',
+ sPrefixed.substring(EValuePrefixes.S_SYMBOLIC.length)]
+ ]);
+ }
+ },
+ /**
+ * Sorts primitive values with regard to the difference in the
+ * number of terminal symbols between the original source text
+ * and the one with those primitive values consolidated.
+ * @param {string} sPrefixed0 The prefixed representation String
+ * of the first of the two primitive values that are being
+ * compared.
+ * @param {string} sPrefixed1 The prefixed representation String
+ * of the second of the two primitive values that are being
+ * compared.
+ * @return {number}
+ * <dl>
+ * <dt>-1</dt>
+ * <dd>if the first primitive value must be placed before
+ * the other one,</dd>
+ * <dt>0</dt>
+ * <dd>if the first primitive value may be placed before
+ * the other one,</dd>
+ * <dt>1</dt>
+ * <dd>if the first primitive value must not be placed
+ * before the other one.</dd>
+ * </dl>
+ * @see TSolution.oPrimitiveValues
+ */
+ cSortPrimitiveValues = function(sPrefixed0, sPrefixed1) {
+ /**
+ * The difference between:
+ * <ol>
+ * <li>the difference in the number of terminal symbols
+ * between the original source text and the one with the
+ * first primitive value consolidated, and</li>
+ * <li>the difference in the number of terminal symbols
+ * between the original source text and the one with the
+ * second primitive value consolidated.</li>
+ * </ol>
+ * @type {number}
+ */
+ var nDifference =
+ oSolutionCandidate.oPrimitiveValues[sPrefixed0].nSaving -
+ oSolutionCandidate.oPrimitiveValues[sPrefixed1].nSaving;
+
+ return nDifference > 0 ? -1 : nDifference < 0 ? 1 : 0;
+ },
+ /**
+ * Assigns an identifier name to a primitive value and calculates
+ * whether instances of that primitive value are worth
+ * consolidating.
+ * @param {string} sPrefixed The prefixed representation String
+ * of a primitive value that is being evaluated.
+ */
+ fEvaluatePrimitiveValue = function(sPrefixed) {
+ var _,
+ /**
+ * The index of the last mangled name.
+ * @type {number}
+ */
+ nIndex,
+ /**
+ * The representation String of the primitive value that is
+ * being evaluated.
+ * @type {string}
+ */
+ sName =
+ sPrefixed.substring(EValuePrefixes.S_SYMBOLIC.length),
+ /**
+ * The number of source characters taken up by the
+ * representation String of the primitive value that is
+ * being evaluated.
+ * @type {number}
+ */
+ nLengthOriginal = sName.length,
+ /**
+ * The number of source characters taken up by the
+ * identifier name that could substitute the primitive
+ * value that is being evaluated.
+ * substituted.
+ * @type {number}
+ */
+ nLengthSubstitution,
+ /**
+ * The number of source characters taken up by by the
+ * representation String of the primitive value that is
+ * being evaluated when it is represented by a string
+ * literal.
+ * @type {number}
+ */
+ nLengthString = oProcessor.make_string(sName).length;
+
+ oSolutionCandidate.oPrimitiveValues[sPrefixed] =
+ new TPrimitiveValue();
+ do { // Find an identifier unused in this or any nested scope.
+ nIndex = oScope.cname;
+ oSolutionCandidate.oPrimitiveValues[sPrefixed].sName =
+ oScope.next_mangled();
+ } while (-1 !== oSourceElementsData.aIdentifiers.indexOf(
+ oSolutionCandidate.oPrimitiveValues[sPrefixed].sName));
+ nLengthSubstitution = oSolutionCandidate.oPrimitiveValues[
+ sPrefixed].sName.length;
+ if (0 === sPrefixed.indexOf(EValuePrefixes.S_SYMBOLIC)) {
+ // foo:null, or foo:null;
+ oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving -=
+ nLengthSubstitution + nLengthOriginal +
+ oWeights.N_VARIABLE_DECLARATION;
+ // null vs foo
+ oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving +=
+ oSourceElementsData.aCount[
+ EPrimaryExpressionCategories.
+ N_NULL_AND_BOOLEAN_LITERALS][sPrefixed] *
+ (nLengthOriginal - nLengthSubstitution);
+ } else {
+ // foo:'fromCharCode';
+ oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving -=
+ nLengthSubstitution + nLengthString +
+ oWeights.N_VARIABLE_DECLARATION;
+ // .fromCharCode vs [foo]
+ if (oSourceElementsData.aCount[
+ EPrimaryExpressionCategories.N_IDENTIFIER_NAMES
+ ].hasOwnProperty(sPrefixed)) {
+ oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving +=
+ oSourceElementsData.aCount[
+ EPrimaryExpressionCategories.N_IDENTIFIER_NAMES
+ ][sPrefixed] *
+ (nLengthOriginal - nLengthSubstitution -
+ oWeights.N_PROPERTY_ACCESSOR);
+ }
+ // 'fromCharCode' vs foo
+ if (oSourceElementsData.aCount[
+ EPrimaryExpressionCategories.N_STRING_LITERALS
+ ].hasOwnProperty(sPrefixed)) {
+ oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving +=
+ oSourceElementsData.aCount[
+ EPrimaryExpressionCategories.N_STRING_LITERALS
+ ][sPrefixed] *
+ (nLengthString - nLengthSubstitution);
+ }
+ }
+ if (oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving >
+ 0) {
+ oSolutionCandidate.nSavings +=
+ oSolutionCandidate.oPrimitiveValues[sPrefixed].nSaving;
+ } else {
+ oScope.cname = nIndex; // Free the identifier name.
+ }
+ },
+ /**
+ * Adds a variable declaration to an existing variable statement.
+ * @param {!Array} aVariableDeclaration A variable declaration
+ * with an initialiser.
+ */
+ cAddVariableDeclaration = function(aVariableDeclaration) {
+ (/** @type {!Array} */ oSourceElements[nFrom][1]).unshift(
+ aVariableDeclaration);
+ };
+
+ if (nFrom > nTo) {
+ return;
+ }
+ // If the range is a closure, reuse the closure.
+ if (nFrom === nTo &&
+ 'stat' === oSourceElements[nFrom][0] &&
+ 'call' === oSourceElements[nFrom][1][0] &&
+ 'function' === oSourceElements[nFrom][1][1][0]) {
+ fExamineSyntacticCodeUnit(oSourceElements[nFrom][1][1]);
+ return;
+ }
+ // Create a list of all derived primitive values within the range.
+ for (nPosition = nFrom; nPosition <= nTo; nPosition += 1) {
+ aSourceElementsData[nPosition].aPrimitiveValues.forEach(
+ cAugmentList(oSourceElementsData.aPrimitiveValues));
+ }
+ if (0 === oSourceElementsData.aPrimitiveValues.length) {
+ return;
+ }
+ for (nPosition = nFrom; nPosition <= nTo; nPosition += 1) {
+ // Add the number of occurrences to the total count.
+ fAddOccurrences(nPosition);
+ // Add identifiers of this or any nested scope to the list.
+ aSourceElementsData[nPosition].aIdentifiers.forEach(
+ cAugmentList(oSourceElementsData.aIdentifiers));
+ }
+ // Distribute identifier names among derived primitive values.
+ do { // If there was any progress, find a better distribution.
+ oSolutionBest = oSolutionCandidate;
+ if (Object.keys(oSolutionCandidate.oPrimitiveValues).length > 0) {
+ // Sort primitive values descending by their worthwhileness.
+ oSourceElementsData.aPrimitiveValues.sort(cSortPrimitiveValues);
+ }
+ oSolutionCandidate = new TSolution();
+ oSourceElementsData.aPrimitiveValues.forEach(
+ fEvaluatePrimitiveValue);
+ oScope.cname = nIndex;
+ } while (oSolutionCandidate.nSavings > oSolutionBest.nSavings);
+ // Take the necessity of adding a variable statement into account.
+ if ('var' !== oSourceElements[nFrom][0]) {
+ oSolutionBest.nSavings -= oWeights.N_VARIABLE_STATEMENT_AFFIXATION;
+ }
+ if (bEnclose) {
+ // Take the necessity of forming a closure into account.
+ oSolutionBest.nSavings -= oWeights.N_CLOSURE;
+ }
+ if (oSolutionBest.nSavings > 0) {
+ // Create variable declarations suitable for UglifyJS.
+ Object.keys(oSolutionBest.oPrimitiveValues).forEach(
+ cAugmentVariableDeclarations);
+ // Rewrite expressions that contain worthwhile primitive values.
+ for (nPosition = nFrom; nPosition <= nTo; nPosition += 1) {
+ oWalker = oProcessor.ast_walker();
+ oSourceElements[nPosition] =
+ oWalker.with_walkers(
+ oWalkersTransformers,
+ cContext(oWalker, oSourceElements[nPosition]));
+ }
+ if ('var' === oSourceElements[nFrom][0]) { // Reuse the statement.
+ (/** @type {!Array.<!Array>} */ aVariableDeclarations.reverse(
+ )).forEach(cAddVariableDeclaration);
+ } else { // Add a variable statement.
+ Array.prototype.splice.call(
+ oSourceElements,
+ nFrom,
+ 0,
+ ['var', aVariableDeclarations]);
+ nTo += 1;
+ }
+ if (bEnclose) {
+ // Add a closure.
+ Array.prototype.splice.call(
+ oSourceElements,
+ nFrom,
+ 0,
+ ['stat', ['call', ['function', null, [], []], []]]);
+ // Copy source elements into the closure.
+ for (nPosition = nTo + 1; nPosition > nFrom; nPosition -= 1) {
+ Array.prototype.unshift.call(
+ oSourceElements[nFrom][1][1][3],
+ oSourceElements[nPosition]);
+ }
+ // Remove source elements outside the closure.
+ Array.prototype.splice.call(
+ oSourceElements,
+ nFrom + 1,
+ nTo - nFrom + 1);
+ }
+ }
+ if (bEnclose) {
+ // Restore the availability of identifier names.
+ oScope.cname = nIndex;
+ }
+ };
+
+ oSourceElements = (/** @type {!TSyntacticCodeUnit} */
+ oSyntacticCodeUnit[bIsGlobal ? 1 : 3]);
+ if (0 === oSourceElements.length) {
+ return;
+ }
+ oScope = bIsGlobal ? oSyntacticCodeUnit.scope : oSourceElements.scope;
+ // Skip a Directive Prologue.
+ while (nAfterDirectivePrologue < oSourceElements.length &&
+ 'directive' === oSourceElements[nAfterDirectivePrologue][0]) {
+ nAfterDirectivePrologue += 1;
+ aSourceElementsData.push(null);
+ }
+ if (oSourceElements.length === nAfterDirectivePrologue) {
+ return;
+ }
+ for (nPosition = nAfterDirectivePrologue;
+ nPosition < oSourceElements.length;
+ nPosition += 1) {
+ oSourceElementData = new TSourceElementsData();
+ oWalker = oProcessor.ast_walker();
+ // Classify a source element.
+ // Find its derived primitive values and count their occurrences.
+ // Find all identifiers used (including nested scopes).
+ oWalker.with_walkers(
+ oWalkers.oSurveySourceElement,
+ cContext(oWalker, oSourceElements[nPosition]));
+ // Establish whether the scope is still wholly examinable.
+ bIsWhollyExaminable = bIsWhollyExaminable &&
+ ESourceElementCategories.N_WITH !== oSourceElementData.nCategory &&
+ ESourceElementCategories.N_EVAL !== oSourceElementData.nCategory;
+ aSourceElementsData.push(oSourceElementData);
+ }
+ if (bIsWhollyExaminable) { // Examine the whole scope.
+ fExamineSourceElements(
+ nAfterDirectivePrologue,
+ oSourceElements.length - 1,
+ false);
+ } else { // Examine unexcluded ranges of source elements.
+ for (nPosition = oSourceElements.length - 1;
+ nPosition >= nAfterDirectivePrologue;
+ nPosition -= 1) {
+ oSourceElementData = (/** @type {!TSourceElementsData} */
+ aSourceElementsData[nPosition]);
+ if (ESourceElementCategories.N_OTHER ===
+ oSourceElementData.nCategory) {
+ if ('undefined' === typeof nTo) {
+ nTo = nPosition; // Indicate the end of a range.
+ }
+ // Examine the range if it immediately follows a Directive Prologue.
+ if (nPosition === nAfterDirectivePrologue) {
+ fExamineSourceElements(nPosition, nTo, true);
+ }
+ } else {
+ if ('undefined' !== typeof nTo) {
+ // Examine the range that immediately follows this source element.
+ fExamineSourceElements(nPosition + 1, nTo, true);
+ nTo = void 0; // Obliterate the range.
+ }
+ // Examine nested functions.
+ oWalker = oProcessor.ast_walker();
+ oWalker.with_walkers(
+ oWalkers.oExamineFunctions,
+ cContext(oWalker, oSourceElements[nPosition]));
+ }
+ }
+ }
+ }(oAbstractSyntaxTree = oProcessor.ast_add_scope(oAbstractSyntaxTree)));
+ return oAbstractSyntaxTree;
+};
+/*jshint sub:false */
+
+/* Local Variables: */
+/* mode: js */
+/* coding: utf-8 */
+/* indent-tabs-mode: nil */
+/* tab-width: 2 */
+/* End: */
+/* vim: set ft=javascript fenc=utf-8 et ts=2 sts=2 sw=2: */
+/* :mode=javascript:noTabs=true:tabSize=2:indentSize=2:deepIndent=true: */
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjslibparsejsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/parse-js.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/parse-js.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/parse-js.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,1364 @@
</span><ins>+/***********************************************************************
+
+ A JavaScript tokenizer / parser / beautifier / compressor.
+
+ This version is suitable for Node.js. With minimal changes (the
+ exports stuff) it should work on any JS platform.
+
+ This file contains the tokenizer/parser. It is a port to JavaScript
+ of parse-js [1], a JavaScript parser library written in Common Lisp
+ by Marijn Haverbeke. Thank you Marijn!
+
+ [1] http://marijn.haverbeke.nl/parse-js/
+
+ Exported functions:
+
+ - tokenizer(code) -- returns a function. Call the returned
+ function to fetch the next token.
+
+ - parse(code) -- returns an AST of the given JavaScript code.
+
+ -------------------------------- (C) ---------------------------------
+
+ Author: Mihai Bazon
+ <mihai.bazon@gmail.com>
+ http://mihai.bazon.net/blog
+
+ Distributed under the BSD license:
+
+ Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
+ Based on parse-js (http://marijn.haverbeke.nl/parse-js/).
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ ***********************************************************************/
+
+/* -----[ Tokenizer (constants) ]----- */
+
+var KEYWORDS = array_to_hash([
+ "break",
+ "case",
+ "catch",
+ "const",
+ "continue",
+ "debugger",
+ "default",
+ "delete",
+ "do",
+ "else",
+ "finally",
+ "for",
+ "function",
+ "if",
+ "in",
+ "instanceof",
+ "new",
+ "return",
+ "switch",
+ "throw",
+ "try",
+ "typeof",
+ "var",
+ "void",
+ "while",
+ "with"
+]);
+
+var RESERVED_WORDS = array_to_hash([
+ "abstract",
+ "boolean",
+ "byte",
+ "char",
+ "class",
+ "double",
+ "enum",
+ "export",
+ "extends",
+ "final",
+ "float",
+ "goto",
+ "implements",
+ "import",
+ "int",
+ "interface",
+ "long",
+ "native",
+ "package",
+ "private",
+ "protected",
+ "public",
+ "short",
+ "static",
+ "super",
+ "synchronized",
+ "throws",
+ "transient",
+ "volatile"
+]);
+
+var KEYWORDS_BEFORE_EXPRESSION = array_to_hash([
+ "return",
+ "new",
+ "delete",
+ "throw",
+ "else",
+ "case"
+]);
+
+var KEYWORDS_ATOM = array_to_hash([
+ "false",
+ "null",
+ "true",
+ "undefined"
+]);
+
+var OPERATOR_CHARS = array_to_hash(characters("+-*&%=<>!?|~^"));
+
+var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
+var RE_OCT_NUMBER = /^0[0-7]+$/;
+var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
+
+var OPERATORS = array_to_hash([
+ "in",
+ "instanceof",
+ "typeof",
+ "new",
+ "void",
+ "delete",
+ "++",
+ "--",
+ "+",
+ "-",
+ "!",
+ "~",
+ "&",
+ "|",
+ "^",
+ "*",
+ "/",
+ "%",
+ ">>",
+ "<<",
+ ">>>",
+ "<",
+ ">",
+ "<=",
+ ">=",
+ "==",
+ "===",
+ "!=",
+ "!==",
+ "?",
+ "=",
+ "+=",
+ "-=",
+ "/=",
+ "*=",
+ "%=",
+ ">>=",
+ "<<=",
+ ">>>=",
+ "|=",
+ "^=",
+ "&=",
+ "&&",
+ "||"
+]);
+
+var WHITESPACE_CHARS = array_to_hash(characters(" \u00a0\n\r\t\f\u000b\u200b\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000"));
+
+var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{(,.;:"));
+
+var PUNC_CHARS = array_to_hash(characters("[]{}(),;:"));
+
+var REGEXP_MODIFIERS = array_to_hash(characters("gmsiy"));
+
+/* -----[ Tokenizer ]----- */
+
+var UNICODE = { // Unicode 6.1
+ letter: new RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0\\u08A2-\\u08AC\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0977\\u0979-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0
A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\
u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F0\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\
u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA6
7F-\\uA697\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA793\\uA7A0-\\uA7AA\\uA7F8-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA80-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"),
+ combining_mark: new RegExp("[\\u0300-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065F\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0859-\\u085B\\u08E4-\\u08FE\\u0900-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962\\u0963\\u0981-\\u0983\\u09BC\\u09BE-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CD\\u09D7\\u09E2\\u09E3\\u0A01-\\u0A03\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81-\\u0A83\\u0ABC\\u0ABE-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AE2\\u0AE3\\u0B01-\\u0B03\\u0B3C\\u0B3E-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B62\\u0B63\\u0B82\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD7\\u0C01-\\u0C03\\u0C3E-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0C82\\u0C83\\u0CBC\\u0CBE-\\u0CC4\\u0CC6-\\u0CC8\\
u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CE2\\u0CE3\\u0D02\\u0D03\\u0D3E-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4D\\u0D57\\u0D62\\u0D63\\u0D82\\u0D83\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F3E\\u0F3F\\u0F71-\\u0F84\\u0F86\\u0F87\\u0F8D-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102B-\\u103E\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F\\u109A-\\u109D\\u135D-\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B4-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u192B\\u1930-\\u193B\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A17-\\u1A1B\\u1A55-\\u1A5E\\u1A60-\\u1A7C\\u1A7F\\u1B00-\\u1B04\\u1B34-\\u1B44\\u1B6B-\\u1B73\\u1B80-\\u1B82\\u1BA1-\\u1BAD\\u1BE6-\\u1BF3\\u1C24-\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE8\\u1CED\\u1CF2-\\u1CF4\\u1DC0-\\u1DE6\\u1DFC-\\u1DFF\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2D7F
\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA674-\\uA67D\\uA69F\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA823-\\uA827\\uA880\\uA881\\uA8B4-\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA953\\uA980-\\uA983\\uA9B3-\\uA9C0\\uAA29-\\uAA36\\uAA43\\uAA4C\\uAA4D\\uAA7B\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAEB-\\uAAEF\\uAAF5\\uAAF6\\uABE3-\\uABEA\\uABEC\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE26]"),
+ connector_punctuation: new RegExp("[\\u005F\\u203F\\u2040\\u2054\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFF3F]"),
+ digit: new RegExp("[\\u0030-\\u0039\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0BE6-\\u0BEF\\u0C66-\\u0C6F\\u0CE6-\\u0CEF\\u0D66-\\u0D6F\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F29\\u1040-\\u1049\\u1090-\\u1099\\u17E0-\\u17E9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19D9\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\uA620-\\uA629\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19]")
+};
+
+function is_letter(ch) {
+ return UNICODE.letter.test(ch);
+};
+
+function is_digit(ch) {
+ ch = ch.charCodeAt(0);
+ return ch >= 48 && ch <= 57;
+};
+
+function is_unicode_digit(ch) {
+ return UNICODE.digit.test(ch);
+}
+
+function is_alphanumeric_char(ch) {
+ return is_digit(ch) || is_letter(ch);
+};
+
+function is_unicode_combining_mark(ch) {
+ return UNICODE.combining_mark.test(ch);
+};
+
+function is_unicode_connector_punctuation(ch) {
+ return UNICODE.connector_punctuation.test(ch);
+};
+
+function is_identifier_start(ch) {
+ return ch == "$" || ch == "_" || is_letter(ch);
+};
+
+function is_identifier_char(ch) {
+ return is_identifier_start(ch)
+ || is_unicode_combining_mark(ch)
+ || is_unicode_digit(ch)
+ || is_unicode_connector_punctuation(ch)
+ || ch == "\u200c" // zero-width non-joiner <ZWNJ>
+ || ch == "\u200d" // zero-width joiner <ZWJ> (in my ECMA-262 PDF, this is also 200c)
+ ;
+};
+
+function parse_js_number(num) {
+ if (RE_HEX_NUMBER.test(num)) {
+ return parseInt(num.substr(2), 16);
+ } else if (RE_OCT_NUMBER.test(num)) {
+ return parseInt(num.substr(1), 8);
+ } else if (RE_DEC_NUMBER.test(num)) {
+ return parseFloat(num);
+ }
+};
+
+function JS_Parse_Error(message, line, col, pos) {
+ this.message = message;
+ this.line = line + 1;
+ this.col = col + 1;
+ this.pos = pos + 1;
+ this.stack = new Error().stack;
+};
+
+JS_Parse_Error.prototype.toString = function() {
+ return this.message + " (line: " + this.line + ", col: " + this.col + ", pos: " + this.pos + ")" + "\n\n" + this.stack;
+};
+
+function js_error(message, line, col, pos) {
+ throw new JS_Parse_Error(message, line, col, pos);
+};
+
+function is_token(token, type, val) {
+ return token.type == type && (val == null || token.value == val);
+};
+
+var EX_EOF = {};
+
+function tokenizer($TEXT) {
+
+ var S = {
+ text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''),
+ pos : 0,
+ tokpos : 0,
+ line : 0,
+ tokline : 0,
+ col : 0,
+ tokcol : 0,
+ newline_before : false,
+ regex_allowed : false,
+ comments_before : []
+ };
+
+ function peek() { return S.text.charAt(S.pos); };
+
+ function next(signal_eof, in_string) {
+ var ch = S.text.charAt(S.pos++);
+ if (signal_eof && !ch)
+ throw EX_EOF;
+ if (ch == "\n") {
+ S.newline_before = S.newline_before || !in_string;
+ ++S.line;
+ S.col = 0;
+ } else {
+ ++S.col;
+ }
+ return ch;
+ };
+
+ function eof() {
+ return !S.peek();
+ };
+
+ function find(what, signal_eof) {
+ var pos = S.text.indexOf(what, S.pos);
+ if (signal_eof && pos == -1) throw EX_EOF;
+ return pos;
+ };
+
+ function start_token() {
+ S.tokline = S.line;
+ S.tokcol = S.col;
+ S.tokpos = S.pos;
+ };
+
+ function token(type, value, is_comment) {
+ S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) ||
+ (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) ||
+ (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value)));
+ var ret = {
+ type : type,
+ value : value,
+ line : S.tokline,
+ col : S.tokcol,
+ pos : S.tokpos,
+ endpos : S.pos,
+ nlb : S.newline_before
+ };
+ if (!is_comment) {
+ ret.comments_before = S.comments_before;
+ S.comments_before = [];
+ // make note of any newlines in the comments that came before
+ for (var i = 0, len = ret.comments_before.length; i < len; i++) {
+ ret.nlb = ret.nlb || ret.comments_before[i].nlb;
+ }
+ }
+ S.newline_before = false;
+ return ret;
+ };
+
+ function skip_whitespace() {
+ while (HOP(WHITESPACE_CHARS, peek()))
+ next();
+ };
+
+ function read_while(pred) {
+ var ret = "", ch = peek(), i = 0;
+ while (ch && pred(ch, i++)) {
+ ret += next();
+ ch = peek();
+ }
+ return ret;
+ };
+
+ function parse_error(err) {
+ js_error(err, S.tokline, S.tokcol, S.tokpos);
+ };
+
+ function read_num(prefix) {
+ var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
+ var num = read_while(function(ch, i){
+ if (ch == "x" || ch == "X") {
+ if (has_x) return false;
+ return has_x = true;
+ }
+ if (!has_x && (ch == "E" || ch == "e")) {
+ if (has_e) return false;
+ return has_e = after_e = true;
+ }
+ if (ch == "-") {
+ if (after_e || (i == 0 && !prefix)) return true;
+ return false;
+ }
+ if (ch == "+") return after_e;
+ after_e = false;
+ if (ch == ".") {
+ if (!has_dot && !has_x && !has_e)
+ return has_dot = true;
+ return false;
+ }
+ return is_alphanumeric_char(ch);
+ });
+ if (prefix)
+ num = prefix + num;
+ var valid = parse_js_number(num);
+ if (!isNaN(valid)) {
+ return token("num", valid);
+ } else {
+ parse_error("Invalid syntax: " + num);
+ }
+ };
+
+ function read_escaped_char(in_string) {
+ var ch = next(true, in_string);
+ switch (ch) {
+ case "n" : return "\n";
+ case "r" : return "\r";
+ case "t" : return "\t";
+ case "b" : return "\b";
+ case "v" : return "\u000b";
+ case "f" : return "\f";
+ case "0" : return "\0";
+ case "x" : return String.fromCharCode(hex_bytes(2));
+ case "u" : return String.fromCharCode(hex_bytes(4));
+ case "\n": return "";
+ default : return ch;
+ }
+ };
+
+ function hex_bytes(n) {
+ var num = 0;
+ for (; n > 0; --n) {
+ var digit = parseInt(next(true), 16);
+ if (isNaN(digit))
+ parse_error("Invalid hex-character pattern in string");
+ num = (num << 4) | digit;
+ }
+ return num;
+ };
+
+ function read_string() {
+ return with_eof_error("Unterminated string constant", function(){
+ var quote = next(), ret = "";
+ for (;;) {
+ var ch = next(true);
+ if (ch == "\\") {
+ // read OctalEscapeSequence (XXX: deprecated if "strict mode")
+ // https://github.com/mishoo/UglifyJS/issues/178
+ var octal_len = 0, first = null;
+ ch = read_while(function(ch){
+ if (ch >= "0" && ch <= "7") {
+ if (!first) {
+ first = ch;
+ return ++octal_len;
+ }
+ else if (first <= "3" && octal_len <= 2) return ++octal_len;
+ else if (first >= "4" && octal_len <= 1) return ++octal_len;
+ }
+ return false;
+ });
+ if (octal_len > 0) ch = String.fromCharCode(parseInt(ch, 8));
+ else ch = read_escaped_char(true);
+ }
+ else if (ch == quote) break;
+ ret += ch;
+ }
+ return token("string", ret);
+ });
+ };
+
+ function read_line_comment() {
+ next();
+ var i = find("\n"), ret;
+ if (i == -1) {
+ ret = S.text.substr(S.pos);
+ S.pos = S.text.length;
+ } else {
+ ret = S.text.substring(S.pos, i);
+ S.pos = i;
+ }
+ return token("comment1", ret, true);
+ };
+
+ function read_multiline_comment() {
+ next();
+ return with_eof_error("Unterminated multiline comment", function(){
+ var i = find("*/", true),
+ text = S.text.substring(S.pos, i);
+ S.pos = i + 2;
+ S.line += text.split("\n").length - 1;
+ S.newline_before = S.newline_before || text.indexOf("\n") >= 0;
+
+ // https://github.com/mishoo/UglifyJS/issues/#issue/100
+ if (/^@cc_on/i.test(text)) {
+ warn("WARNING: at line " + S.line);
+ warn("*** Found \"conditional comment\": " + text);
+ warn("*** UglifyJS DISCARDS ALL COMMENTS. This means your code might no longer work properly in Internet Explorer.");
+ }
+
+ return token("comment2", text, true);
+ });
+ };
+
+ function read_name() {
+ var backslash = false, name = "", ch, escaped = false, hex;
+ while ((ch = peek()) != null) {
+ if (!backslash) {
+ if (ch == "\\") escaped = backslash = true, next();
+ else if (is_identifier_char(ch)) name += next();
+ else break;
+ }
+ else {
+ if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX");
+ ch = read_escaped_char();
+ if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier");
+ name += ch;
+ backslash = false;
+ }
+ }
+ if (HOP(KEYWORDS, name) && escaped) {
+ hex = name.charCodeAt(0).toString(16).toUpperCase();
+ name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1);
+ }
+ return name;
+ };
+
+ function read_regexp(regexp) {
+ return with_eof_error("Unterminated regular expression", function(){
+ var prev_backslash = false, ch, in_class = false;
+ while ((ch = next(true))) if (prev_backslash) {
+ regexp += "\\" + ch;
+ prev_backslash = false;
+ } else if (ch == "[") {
+ in_class = true;
+ regexp += ch;
+ } else if (ch == "]" && in_class) {
+ in_class = false;
+ regexp += ch;
+ } else if (ch == "/" && !in_class) {
+ break;
+ } else if (ch == "\\") {
+ prev_backslash = true;
+ } else {
+ regexp += ch;
+ }
+ var mods = read_name();
+ return token("regexp", [ regexp, mods ]);
+ });
+ };
+
+ function read_operator(prefix) {
+ function grow(op) {
+ if (!peek()) return op;
+ var bigger = op + peek();
+ if (HOP(OPERATORS, bigger)) {
+ next();
+ return grow(bigger);
+ } else {
+ return op;
+ }
+ };
+ return token("operator", grow(prefix || next()));
+ };
+
+ function handle_slash() {
+ next();
+ var regex_allowed = S.regex_allowed;
+ switch (peek()) {
+ case "/":
+ S.comments_before.push(read_line_comment());
+ S.regex_allowed = regex_allowed;
+ return next_token();
+ case "*":
+ S.comments_before.push(read_multiline_comment());
+ S.regex_allowed = regex_allowed;
+ return next_token();
+ }
+ return S.regex_allowed ? read_regexp("") : read_operator("/");
+ };
+
+ function handle_dot() {
+ next();
+ return is_digit(peek())
+ ? read_num(".")
+ : token("punc", ".");
+ };
+
+ function read_word() {
+ var word = read_name();
+ return !HOP(KEYWORDS, word)
+ ? token("name", word)
+ : HOP(OPERATORS, word)
+ ? token("operator", word)
+ : HOP(KEYWORDS_ATOM, word)
+ ? token("atom", word)
+ : token("keyword", word);
+ };
+
+ function with_eof_error(eof_error, cont) {
+ try {
+ return cont();
+ } catch(ex) {
+ if (ex === EX_EOF) parse_error(eof_error);
+ else throw ex;
+ }
+ };
+
+ function next_token(force_regexp) {
+ if (force_regexp != null)
+ return read_regexp(force_regexp);
+ skip_whitespace();
+ start_token();
+ var ch = peek();
+ if (!ch) return token("eof");
+ if (is_digit(ch)) return read_num();
+ if (ch == '"' || ch == "'") return read_string();
+ if (HOP(PUNC_CHARS, ch)) return token("punc", next());
+ if (ch == ".") return handle_dot();
+ if (ch == "/") return handle_slash();
+ if (HOP(OPERATOR_CHARS, ch)) return read_operator();
+ if (ch == "\\" || is_identifier_start(ch)) return read_word();
+ parse_error("Unexpected character '" + ch + "'");
+ };
+
+ next_token.context = function(nc) {
+ if (nc) S = nc;
+ return S;
+ };
+
+ return next_token;
+
+};
+
+/* -----[ Parser (constants) ]----- */
+
+var UNARY_PREFIX = array_to_hash([
+ "typeof",
+ "void",
+ "delete",
+ "--",
+ "++",
+ "!",
+ "~",
+ "-",
+ "+"
+]);
+
+var UNARY_POSTFIX = array_to_hash([ "--", "++" ]);
+
+var ASSIGNMENT = (function(a, ret, i){
+ while (i < a.length) {
+ ret[a[i]] = a[i].substr(0, a[i].length - 1);
+ i++;
+ }
+ return ret;
+})(
+ ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&="],
+ { "=": true },
+ 0
+);
+
+var PRECEDENCE = (function(a, ret){
+ for (var i = 0, n = 1; i < a.length; ++i, ++n) {
+ var b = a[i];
+ for (var j = 0; j < b.length; ++j) {
+ ret[b[j]] = n;
+ }
+ }
+ return ret;
+})(
+ [
+ ["||"],
+ ["&&"],
+ ["|"],
+ ["^"],
+ ["&"],
+ ["==", "===", "!=", "!=="],
+ ["<", ">", "<=", ">=", "in", "instanceof"],
+ [">>", "<<", ">>>"],
+ ["+", "-"],
+ ["*", "/", "%"]
+ ],
+ {}
+);
+
+var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]);
+
+var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]);
+
+/* -----[ Parser ]----- */
+
+function NodeWithToken(str, start, end) {
+ this.name = str;
+ this.start = start;
+ this.end = end;
+};
+
+NodeWithToken.prototype.toString = function() { return this.name; };
+
+function parse($TEXT, exigent_mode, embed_tokens) {
+
+ var S = {
+ input : typeof $TEXT == "string" ? tokenizer($TEXT, true) : $TEXT,
+ token : null,
+ prev : null,
+ peeked : null,
+ in_function : 0,
+ in_directives : true,
+ in_loop : 0,
+ labels : []
+ };
+
+ S.token = next();
+
+ function is(type, value) {
+ return is_token(S.token, type, value);
+ };
+
+ function peek() { return S.peeked || (S.peeked = S.input()); };
+
+ function next() {
+ S.prev = S.token;
+ if (S.peeked) {
+ S.token = S.peeked;
+ S.peeked = null;
+ } else {
+ S.token = S.input();
+ }
+ S.in_directives = S.in_directives && (
+ S.token.type == "string" || is("punc", ";")
+ );
+ return S.token;
+ };
+
+ function prev() {
+ return S.prev;
+ };
+
+ function croak(msg, line, col, pos) {
+ var ctx = S.input.context();
+ js_error(msg,
+ line != null ? line : ctx.tokline,
+ col != null ? col : ctx.tokcol,
+ pos != null ? pos : ctx.tokpos);
+ };
+
+ function token_error(token, msg) {
+ croak(msg, token.line, token.col);
+ };
+
+ function unexpected(token) {
+ if (token == null)
+ token = S.token;
+ token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
+ };
+
+ function expect_token(type, val) {
+ if (is(type, val)) {
+ return next();
+ }
+ token_error(S.token, "Unexpected token " + S.token.type + ", expected " + type);
+ };
+
+ function expect(punc) { return expect_token("punc", punc); };
+
+ function can_insert_semicolon() {
+ return !exigent_mode && (
+ S.token.nlb || is("eof") || is("punc", "}")
+ );
+ };
+
+ function semicolon() {
+ if (is("punc", ";")) next();
+ else if (!can_insert_semicolon()) unexpected();
+ };
+
+ function as() {
+ return slice(arguments);
+ };
+
+ function parenthesised() {
+ expect("(");
+ var ex = expression();
+ expect(")");
+ return ex;
+ };
+
+ function add_tokens(str, start, end) {
+ return str instanceof NodeWithToken ? str : new NodeWithToken(str, start, end);
+ };
+
+ function maybe_embed_tokens(parser) {
+ if (embed_tokens) return function() {
+ var start = S.token;
+ var ast = parser.apply(this, arguments);
+ ast[0] = add_tokens(ast[0], start, prev());
+ return ast;
+ };
+ else return parser;
+ };
+
+ var statement = maybe_embed_tokens(function() {
+ if (is("operator", "/") || is("operator", "/=")) {
+ S.peeked = null;
+ S.token = S.input(S.token.value.substr(1)); // force regexp
+ }
+ switch (S.token.type) {
+ case "string":
+ var dir = S.in_directives, stat = simple_statement();
+ if (dir && stat[1][0] == "string" && !is("punc", ","))
+ return as("directive", stat[1][1]);
+ return stat;
+ case "num":
+ case "regexp":
+ case "operator":
+ case "atom":
+ return simple_statement();
+
+ case "name":
+ return is_token(peek(), "punc", ":")
+ ? labeled_statement(prog1(S.token.value, next, next))
+ : simple_statement();
+
+ case "punc":
+ switch (S.token.value) {
+ case "{":
+ return as("block", block_());
+ case "[":
+ case "(":
+ return simple_statement();
+ case ";":
+ next();
+ return as("block");
+ default:
+ unexpected();
+ }
+
+ case "keyword":
+ switch (prog1(S.token.value, next)) {
+ case "break":
+ return break_cont("break");
+
+ case "continue":
+ return break_cont("continue");
+
+ case "debugger":
+ semicolon();
+ return as("debugger");
+
+ case "do":
+ return (function(body){
+ expect_token("keyword", "while");
+ return as("do", prog1(parenthesised, semicolon), body);
+ })(in_loop(statement));
+
+ case "for":
+ return for_();
+
+ case "function":
+ return function_(true);
+
+ case "if":
+ return if_();
+
+ case "return":
+ if (S.in_function == 0)
+ croak("'return' outside of function");
+ return as("return",
+ is("punc", ";")
+ ? (next(), null)
+ : can_insert_semicolon()
+ ? null
+ : prog1(expression, semicolon));
+
+ case "switch":
+ return as("switch", parenthesised(), switch_block_());
+
+ case "throw":
+ if (S.token.nlb)
+ croak("Illegal newline after 'throw'");
+ return as("throw", prog1(expression, semicolon));
+
+ case "try":
+ return try_();
+
+ case "var":
+ return prog1(var_, semicolon);
+
+ case "const":
+ return prog1(const_, semicolon);
+
+ case "while":
+ return as("while", parenthesised(), in_loop(statement));
+
+ case "with":
+ return as("with", parenthesised(), statement());
+
+ default:
+ unexpected();
+ }
+ }
+ });
+
+ function labeled_statement(label) {
+ S.labels.push(label);
+ var start = S.token, stat = statement();
+ if (exigent_mode && !HOP(STATEMENTS_WITH_LABELS, stat[0]))
+ unexpected(start);
+ S.labels.pop();
+ return as("label", label, stat);
+ };
+
+ function simple_statement() {
+ return as("stat", prog1(expression, semicolon));
+ };
+
+ function break_cont(type) {
+ var name;
+ if (!can_insert_semicolon()) {
+ name = is("name") ? S.token.value : null;
+ }
+ if (name != null) {
+ next();
+ if (!member(name, S.labels))
+ croak("Label " + name + " without matching loop or statement");
+ }
+ else if (S.in_loop == 0)
+ croak(type + " not inside a loop or switch");
+ semicolon();
+ return as(type, name);
+ };
+
+ function for_() {
+ expect("(");
+ var init = null;
+ if (!is("punc", ";")) {
+ init = is("keyword", "var")
+ ? (next(), var_(true))
+ : expression(true, true);
+ if (is("operator", "in")) {
+ if (init[0] == "var" && init[1].length > 1)
+ croak("Only one variable declaration allowed in for..in loop");
+ return for_in(init);
+ }
+ }
+ return regular_for(init);
+ };
+
+ function regular_for(init) {
+ expect(";");
+ var test = is("punc", ";") ? null : expression();
+ expect(";");
+ var step = is("punc", ")") ? null : expression();
+ expect(")");
+ return as("for", init, test, step, in_loop(statement));
+ };
+
+ function for_in(init) {
+ var lhs = init[0] == "var" ? as("name", init[1][0]) : init;
+ next();
+ var obj = expression();
+ expect(")");
+ return as("for-in", init, lhs, obj, in_loop(statement));
+ };
+
+ var function_ = function(in_statement) {
+ var name = is("name") ? prog1(S.token.value, next) : null;
+ if (in_statement && !name)
+ unexpected();
+ expect("(");
+ return as(in_statement ? "defun" : "function",
+ name,
+ // arguments
+ (function(first, a){
+ while (!is("punc", ")")) {
+ if (first) first = false; else expect(",");
+ if (!is("name")) unexpected();
+ a.push(S.token.value);
+ next();
+ }
+ next();
+ return a;
+ })(true, []),
+ // body
+ (function(){
+ ++S.in_function;
+ var loop = S.in_loop;
+ S.in_directives = true;
+ S.in_loop = 0;
+ var a = block_();
+ --S.in_function;
+ S.in_loop = loop;
+ return a;
+ })());
+ };
+
+ function if_() {
+ var cond = parenthesised(), body = statement(), belse;
+ if (is("keyword", "else")) {
+ next();
+ belse = statement();
+ }
+ return as("if", cond, body, belse);
+ };
+
+ function block_() {
+ expect("{");
+ var a = [];
+ while (!is("punc", "}")) {
+ if (is("eof")) unexpected();
+ a.push(statement());
+ }
+ next();
+ return a;
+ };
+
+ var switch_block_ = curry(in_loop, function(){
+ expect("{");
+ var a = [], cur = null;
+ while (!is("punc", "}")) {
+ if (is("eof")) unexpected();
+ if (is("keyword", "case")) {
+ next();
+ cur = [];
+ a.push([ expression(), cur ]);
+ expect(":");
+ }
+ else if (is("keyword", "default")) {
+ next();
+ expect(":");
+ cur = [];
+ a.push([ null, cur ]);
+ }
+ else {
+ if (!cur) unexpected();
+ cur.push(statement());
+ }
+ }
+ next();
+ return a;
+ });
+
+ function try_() {
+ var body = block_(), bcatch, bfinally;
+ if (is("keyword", "catch")) {
+ next();
+ expect("(");
+ if (!is("name"))
+ croak("Name expected");
+ var name = S.token.value;
+ next();
+ expect(")");
+ bcatch = [ name, block_() ];
+ }
+ if (is("keyword", "finally")) {
+ next();
+ bfinally = block_();
+ }
+ if (!bcatch && !bfinally)
+ croak("Missing catch/finally blocks");
+ return as("try", body, bcatch, bfinally);
+ };
+
+ function vardefs(no_in) {
+ var a = [];
+ for (;;) {
+ if (!is("name"))
+ unexpected();
+ var name = S.token.value;
+ next();
+ if (is("operator", "=")) {
+ next();
+ a.push([ name, expression(false, no_in) ]);
+ } else {
+ a.push([ name ]);
+ }
+ if (!is("punc", ","))
+ break;
+ next();
+ }
+ return a;
+ };
+
+ function var_(no_in) {
+ return as("var", vardefs(no_in));
+ };
+
+ function const_() {
+ return as("const", vardefs());
+ };
+
+ function new_() {
+ var newexp = expr_atom(false), args;
+ if (is("punc", "(")) {
+ next();
+ args = expr_list(")");
+ } else {
+ args = [];
+ }
+ return subscripts(as("new", newexp, args), true);
+ };
+
+ var expr_atom = maybe_embed_tokens(function(allow_calls) {
+ if (is("operator", "new")) {
+ next();
+ return new_();
+ }
+ if (is("punc")) {
+ switch (S.token.value) {
+ case "(":
+ next();
+ return subscripts(prog1(expression, curry(expect, ")")), allow_calls);
+ case "[":
+ next();
+ return subscripts(array_(), allow_calls);
+ case "{":
+ next();
+ return subscripts(object_(), allow_calls);
+ }
+ unexpected();
+ }
+ if (is("keyword", "function")) {
+ next();
+ return subscripts(function_(false), allow_calls);
+ }
+ if (HOP(ATOMIC_START_TOKEN, S.token.type)) {
+ var atom = S.token.type == "regexp"
+ ? as("regexp", S.token.value[0], S.token.value[1])
+ : as(S.token.type, S.token.value);
+ return subscripts(prog1(atom, next), allow_calls);
+ }
+ unexpected();
+ });
+
+ function expr_list(closing, allow_trailing_comma, allow_empty) {
+ var first = true, a = [];
+ while (!is("punc", closing)) {
+ if (first) first = false; else expect(",");
+ if (allow_trailing_comma && is("punc", closing)) break;
+ if (is("punc", ",") && allow_empty) {
+ a.push([ "atom", "undefined" ]);
+ } else {
+ a.push(expression(false));
+ }
+ }
+ next();
+ return a;
+ };
+
+ function array_() {
+ return as("array", expr_list("]", !exigent_mode, true));
+ };
+
+ function object_() {
+ var first = true, a = [];
+ while (!is("punc", "}")) {
+ if (first) first = false; else expect(",");
+ if (!exigent_mode && is("punc", "}"))
+ // allow trailing comma
+ break;
+ var type = S.token.type;
+ var name = as_property_name();
+ if (type == "name" && (name == "get" || name == "set") && !is("punc", ":")) {
+ a.push([ as_name(), function_(false), name ]);
+ } else {
+ expect(":");
+ a.push([ name, expression(false) ]);
+ }
+ }
+ next();
+ return as("object", a);
+ };
+
+ function as_property_name() {
+ switch (S.token.type) {
+ case "num":
+ case "string":
+ return prog1(S.token.value, next);
+ }
+ return as_name();
+ };
+
+ function as_name() {
+ switch (S.token.type) {
+ case "name":
+ case "operator":
+ case "keyword":
+ case "atom":
+ return prog1(S.token.value, next);
+ default:
+ unexpected();
+ }
+ };
+
+ function subscripts(expr, allow_calls) {
+ if (is("punc", ".")) {
+ next();
+ return subscripts(as("dot", expr, as_name()), allow_calls);
+ }
+ if (is("punc", "[")) {
+ next();
+ return subscripts(as("sub", expr, prog1(expression, curry(expect, "]"))), allow_calls);
+ }
+ if (allow_calls && is("punc", "(")) {
+ next();
+ return subscripts(as("call", expr, expr_list(")")), true);
+ }
+ return expr;
+ };
+
+ function maybe_unary(allow_calls) {
+ if (is("operator") && HOP(UNARY_PREFIX, S.token.value)) {
+ return make_unary("unary-prefix",
+ prog1(S.token.value, next),
+ maybe_unary(allow_calls));
+ }
+ var val = expr_atom(allow_calls);
+ while (is("operator") && HOP(UNARY_POSTFIX, S.token.value) && !S.token.nlb) {
+ val = make_unary("unary-postfix", S.token.value, val);
+ next();
+ }
+ return val;
+ };
+
+ function make_unary(tag, op, expr) {
+ if ((op == "++" || op == "--") && !is_assignable(expr))
+ croak("Invalid use of " + op + " operator");
+ return as(tag, op, expr);
+ };
+
+ function expr_op(left, min_prec, no_in) {
+ var op = is("operator") ? S.token.value : null;
+ if (op && op == "in" && no_in) op = null;
+ var prec = op != null ? PRECEDENCE[op] : null;
+ if (prec != null && prec > min_prec) {
+ next();
+ var right = expr_op(maybe_unary(true), prec, no_in);
+ return expr_op(as("binary", op, left, right), min_prec, no_in);
+ }
+ return left;
+ };
+
+ function expr_ops(no_in) {
+ return expr_op(maybe_unary(true), 0, no_in);
+ };
+
+ function maybe_conditional(no_in) {
+ var expr = expr_ops(no_in);
+ if (is("operator", "?")) {
+ next();
+ var yes = expression(false);
+ expect(":");
+ return as("conditional", expr, yes, expression(false, no_in));
+ }
+ return expr;
+ };
+
+ function is_assignable(expr) {
+ if (!exigent_mode) return true;
+ switch (expr[0]+"") {
+ case "dot":
+ case "sub":
+ case "new":
+ case "call":
+ return true;
+ case "name":
+ return expr[1] != "this";
+ }
+ };
+
+ function maybe_assign(no_in) {
+ var left = maybe_conditional(no_in), val = S.token.value;
+ if (is("operator") && HOP(ASSIGNMENT, val)) {
+ if (is_assignable(left)) {
+ next();
+ return as("assign", ASSIGNMENT[val], left, maybe_assign(no_in));
+ }
+ croak("Invalid assignment");
+ }
+ return left;
+ };
+
+ var expression = maybe_embed_tokens(function(commas, no_in) {
+ if (arguments.length == 0)
+ commas = true;
+ var expr = maybe_assign(no_in);
+ if (commas && is("punc", ",")) {
+ next();
+ return as("seq", expr, expression(true, no_in));
+ }
+ return expr;
+ });
+
+ function in_loop(cont) {
+ try {
+ ++S.in_loop;
+ return cont();
+ } finally {
+ --S.in_loop;
+ }
+ };
+
+ return as("toplevel", (function(a){
+ while (!is("eof"))
+ a.push(statement());
+ return a;
+ })([]));
+
+};
+
+/* -----[ Utilities ]----- */
+
+function curry(f) {
+ var args = slice(arguments, 1);
+ return function() { return f.apply(this, args.concat(slice(arguments))); };
+};
+
+function prog1(ret) {
+ if (ret instanceof Function)
+ ret = ret();
+ for (var i = 1, n = arguments.length; --n > 0; ++i)
+ arguments[i]();
+ return ret;
+};
+
+function array_to_hash(a) {
+ var ret = {};
+ for (var i = 0; i < a.length; ++i)
+ ret[a[i]] = true;
+ return ret;
+};
+
+function slice(a, start) {
+ return Array.prototype.slice.call(a, start || 0);
+};
+
+function characters(str) {
+ return str.split("");
+};
+
+function member(name, array) {
+ for (var i = array.length; --i >= 0;)
+ if (array[i] == name)
+ return true;
+ return false;
+};
+
+function HOP(obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop);
+};
+
+var warn = function() {};
+
+/* -----[ Exports ]----- */
+
+exports.tokenizer = tokenizer;
+exports.parse = parse;
+exports.slice = slice;
+exports.curry = curry;
+exports.member = member;
+exports.array_to_hash = array_to_hash;
+exports.PRECEDENCE = PRECEDENCE;
+exports.KEYWORDS_ATOM = KEYWORDS_ATOM;
+exports.RESERVED_WORDS = RESERVED_WORDS;
+exports.KEYWORDS = KEYWORDS;
+exports.ATOMIC_START_TOKEN = ATOMIC_START_TOKEN;
+exports.OPERATORS = OPERATORS;
+exports.is_alphanumeric_char = is_alphanumeric_char;
+exports.is_identifier_start = is_identifier_start;
+exports.is_identifier_char = is_identifier_char;
+exports.set_logger = function(logger) {
+ warn = logger;
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjslibprocessjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/process.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/process.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/process.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2091 @@
</span><ins>+/***********************************************************************
+
+ A JavaScript tokenizer / parser / beautifier / compressor.
+
+ This version is suitable for Node.js. With minimal changes (the
+ exports stuff) it should work on any JS platform.
+
+ This file implements some AST processors. They work on data built
+ by parse-js.
+
+ Exported functions:
+
+ - ast_mangle(ast, options) -- mangles the variable/function names
+ in the AST. Returns an AST.
+
+ - ast_squeeze(ast) -- employs various optimizations to make the
+ final generated code even smaller. Returns an AST.
+
+ - gen_code(ast, options) -- generates JS code from the AST. Pass
+ true (or an object, see the code for some options) as second
+ argument to get "pretty" (indented) code.
+
+ -------------------------------- (C) ---------------------------------
+
+ Author: Mihai Bazon
+ <mihai.bazon@gmail.com>
+ http://mihai.bazon.net/blog
+
+ Distributed under the BSD license:
+
+ Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ ***********************************************************************/
+
+var jsp = require("./parse-js"),
+ slice = jsp.slice,
+ member = jsp.member,
+ is_identifier_char = jsp.is_identifier_char,
+ PRECEDENCE = jsp.PRECEDENCE,
+ OPERATORS = jsp.OPERATORS;
+
+/* -----[ helper for AST traversal ]----- */
+
+function ast_walker() {
+ function _vardefs(defs) {
+ return [ this[0], MAP(defs, function(def){
+ var a = [ def[0] ];
+ if (def.length > 1)
+ a[1] = walk(def[1]);
+ return a;
+ }) ];
+ };
+ function _block(statements) {
+ var out = [ this[0] ];
+ if (statements != null)
+ out.push(MAP(statements, walk));
+ return out;
+ };
+ var walkers = {
+ "string": function(str) {
+ return [ this[0], str ];
+ },
+ "num": function(num) {
+ return [ this[0], num ];
+ },
+ "name": function(name) {
+ return [ this[0], name ];
+ },
+ "toplevel": function(statements) {
+ return [ this[0], MAP(statements, walk) ];
+ },
+ "block": _block,
+ "splice": _block,
+ "var": _vardefs,
+ "const": _vardefs,
+ "try": function(t, c, f) {
+ return [
+ this[0],
+ MAP(t, walk),
+ c != null ? [ c[0], MAP(c[1], walk) ] : null,
+ f != null ? MAP(f, walk) : null
+ ];
+ },
+ "throw": function(expr) {
+ return [ this[0], walk(expr) ];
+ },
+ "new": function(ctor, args) {
+ return [ this[0], walk(ctor), MAP(args, walk) ];
+ },
+ "switch": function(expr, body) {
+ return [ this[0], walk(expr), MAP(body, function(branch){
+ return [ branch[0] ? walk(branch[0]) : null,
+ MAP(branch[1], walk) ];
+ }) ];
+ },
+ "break": function(label) {
+ return [ this[0], label ];
+ },
+ "continue": function(label) {
+ return [ this[0], label ];
+ },
+ "conditional": function(cond, t, e) {
+ return [ this[0], walk(cond), walk(t), walk(e) ];
+ },
+ "assign": function(op, lvalue, rvalue) {
+ return [ this[0], op, walk(lvalue), walk(rvalue) ];
+ },
+ "dot": function(expr) {
+ return [ this[0], walk(expr) ].concat(slice(arguments, 1));
+ },
+ "call": function(expr, args) {
+ return [ this[0], walk(expr), MAP(args, walk) ];
+ },
+ "function": function(name, args, body) {
+ return [ this[0], name, args.slice(), MAP(body, walk) ];
+ },
+ "debugger": function() {
+ return [ this[0] ];
+ },
+ "defun": function(name, args, body) {
+ return [ this[0], name, args.slice(), MAP(body, walk) ];
+ },
+ "if": function(conditional, t, e) {
+ return [ this[0], walk(conditional), walk(t), walk(e) ];
+ },
+ "for": function(init, cond, step, block) {
+ return [ this[0], walk(init), walk(cond), walk(step), walk(block) ];
+ },
+ "for-in": function(vvar, key, hash, block) {
+ return [ this[0], walk(vvar), walk(key), walk(hash), walk(block) ];
+ },
+ "while": function(cond, block) {
+ return [ this[0], walk(cond), walk(block) ];
+ },
+ "do": function(cond, block) {
+ return [ this[0], walk(cond), walk(block) ];
+ },
+ "return": function(expr) {
+ return [ this[0], walk(expr) ];
+ },
+ "binary": function(op, left, right) {
+ return [ this[0], op, walk(left), walk(right) ];
+ },
+ "unary-prefix": function(op, expr) {
+ return [ this[0], op, walk(expr) ];
+ },
+ "unary-postfix": function(op, expr) {
+ return [ this[0], op, walk(expr) ];
+ },
+ "sub": function(expr, subscript) {
+ return [ this[0], walk(expr), walk(subscript) ];
+ },
+ "object": function(props) {
+ return [ this[0], MAP(props, function(p){
+ return p.length == 2
+ ? [ p[0], walk(p[1]) ]
+ : [ p[0], walk(p[1]), p[2] ]; // get/set-ter
+ }) ];
+ },
+ "regexp": function(rx, mods) {
+ return [ this[0], rx, mods ];
+ },
+ "array": function(elements) {
+ return [ this[0], MAP(elements, walk) ];
+ },
+ "stat": function(stat) {
+ return [ this[0], walk(stat) ];
+ },
+ "seq": function() {
+ return [ this[0] ].concat(MAP(slice(arguments), walk));
+ },
+ "label": function(name, block) {
+ return [ this[0], name, walk(block) ];
+ },
+ "with": function(expr, block) {
+ return [ this[0], walk(expr), walk(block) ];
+ },
+ "atom": function(name) {
+ return [ this[0], name ];
+ },
+ "directive": function(dir) {
+ return [ this[0], dir ];
+ }
+ };
+
+ var user = {};
+ var stack = [];
+ function walk(ast) {
+ if (ast == null)
+ return null;
+ try {
+ stack.push(ast);
+ var type = ast[0];
+ var gen = user[type];
+ if (gen) {
+ var ret = gen.apply(ast, ast.slice(1));
+ if (ret != null)
+ return ret;
+ }
+ gen = walkers[type];
+ return gen.apply(ast, ast.slice(1));
+ } finally {
+ stack.pop();
+ }
+ };
+
+ function dive(ast) {
+ if (ast == null)
+ return null;
+ try {
+ stack.push(ast);
+ return walkers[ast[0]].apply(ast, ast.slice(1));
+ } finally {
+ stack.pop();
+ }
+ };
+
+ function with_walkers(walkers, cont){
+ var save = {}, i;
+ for (i in walkers) if (HOP(walkers, i)) {
+ save[i] = user[i];
+ user[i] = walkers[i];
+ }
+ var ret = cont();
+ for (i in save) if (HOP(save, i)) {
+ if (!save[i]) delete user[i];
+ else user[i] = save[i];
+ }
+ return ret;
+ };
+
+ return {
+ walk: walk,
+ dive: dive,
+ with_walkers: with_walkers,
+ parent: function() {
+ return stack[stack.length - 2]; // last one is current node
+ },
+ stack: function() {
+ return stack;
+ }
+ };
+};
+
+/* -----[ Scope and mangling ]----- */
+
+function Scope(parent) {
+ this.names = {}; // names defined in this scope
+ this.mangled = {}; // mangled names (orig.name => mangled)
+ this.rev_mangled = {}; // reverse lookup (mangled => orig.name)
+ this.cname = -1; // current mangled name
+ this.refs = {}; // names referenced from this scope
+ this.uses_with = false; // will become TRUE if with() is detected in this or any subscopes
+ this.uses_eval = false; // will become TRUE if eval() is detected in this or any subscopes
+ this.directives = []; // directives activated from this scope
+ this.parent = parent; // parent scope
+ this.children = []; // sub-scopes
+ if (parent) {
+ this.level = parent.level + 1;
+ parent.children.push(this);
+ } else {
+ this.level = 0;
+ }
+};
+
+function base54_digits() {
+ if (typeof DIGITS_OVERRIDE_FOR_TESTING != "undefined")
+ return DIGITS_OVERRIDE_FOR_TESTING;
+ else
+ return "etnrisouaflchpdvmgybwESxTNCkLAOM_DPHBjFIqRUzWXV$JKQGYZ0516372984";
+}
+
+var base54 = (function(){
+ var DIGITS = base54_digits();
+ return function(num) {
+ var ret = "", base = 54;
+ do {
+ ret += DIGITS.charAt(num % base);
+ num = Math.floor(num / base);
+ base = 64;
+ } while (num > 0);
+ return ret;
+ };
+})();
+
+Scope.prototype = {
+ has: function(name) {
+ for (var s = this; s; s = s.parent)
+ if (HOP(s.names, name))
+ return s;
+ },
+ has_mangled: function(mname) {
+ for (var s = this; s; s = s.parent)
+ if (HOP(s.rev_mangled, mname))
+ return s;
+ },
+ toJSON: function() {
+ return {
+ names: this.names,
+ uses_eval: this.uses_eval,
+ uses_with: this.uses_with
+ };
+ },
+
+ next_mangled: function() {
+ // we must be careful that the new mangled name:
+ //
+ // 1. doesn't shadow a mangled name from a parent
+ // scope, unless we don't reference the original
+ // name from this scope OR from any sub-scopes!
+ // This will get slow.
+ //
+ // 2. doesn't shadow an original name from a parent
+ // scope, in the event that the name is not mangled
+ // in the parent scope and we reference that name
+ // here OR IN ANY SUBSCOPES!
+ //
+ // 3. doesn't shadow a name that is referenced but not
+ // defined (possibly global defined elsewhere).
+ for (;;) {
+ var m = base54(++this.cname), prior;
+
+ // case 1.
+ prior = this.has_mangled(m);
+ if (prior && this.refs[prior.rev_mangled[m]] === prior)
+ continue;
+
+ // case 2.
+ prior = this.has(m);
+ if (prior && prior !== this && this.refs[m] === prior && !prior.has_mangled(m))
+ continue;
+
+ // case 3.
+ if (HOP(this.refs, m) && this.refs[m] == null)
+ continue;
+
+ // I got "do" once. :-/
+ if (!is_identifier(m))
+ continue;
+
+ return m;
+ }
+ },
+ set_mangle: function(name, m) {
+ this.rev_mangled[m] = name;
+ return this.mangled[name] = m;
+ },
+ get_mangled: function(name, newMangle) {
+ if (this.uses_eval || this.uses_with) return name; // no mangle if eval or with is in use
+ var s = this.has(name);
+ if (!s) return name; // not in visible scope, no mangle
+ if (HOP(s.mangled, name)) return s.mangled[name]; // already mangled in this scope
+ if (!newMangle) return name; // not found and no mangling requested
+ return s.set_mangle(name, s.next_mangled());
+ },
+ references: function(name) {
+ return name && !this.parent || this.uses_with || this.uses_eval || this.refs[name];
+ },
+ define: function(name, type) {
+ if (name != null) {
+ if (type == "var" || !HOP(this.names, name))
+ this.names[name] = type || "var";
+ return name;
+ }
+ },
+ active: function(dir) {
+ return member(dir, this.directives) || this.parent && this.parent.active(dir);
+ }
+};
+
+function ast_add_scope(ast) {
+
+ var current_scope = null;
+ var w = ast_walker(), walk = w.walk;
+ var having_eval = [];
+
+ function with_new_scope(cont) {
+ current_scope = new Scope(current_scope);
+ current_scope.labels = new Scope();
+ var ret = current_scope.body = cont();
+ ret.scope = current_scope;
+ current_scope = current_scope.parent;
+ return ret;
+ };
+
+ function define(name, type) {
+ return current_scope.define(name, type);
+ };
+
+ function reference(name) {
+ current_scope.refs[name] = true;
+ };
+
+ function _lambda(name, args, body) {
+ var is_defun = this[0] == "defun";
+ return [ this[0], is_defun ? define(name, "defun") : name, args, with_new_scope(function(){
+ if (!is_defun) define(name, "lambda");
+ MAP(args, function(name){ define(name, "arg") });
+ return MAP(body, walk);
+ })];
+ };
+
+ function _vardefs(type) {
+ return function(defs) {
+ MAP(defs, function(d){
+ define(d[0], type);
+ if (d[1]) reference(d[0]);
+ });
+ };
+ };
+
+ function _breacont(label) {
+ if (label)
+ current_scope.labels.refs[label] = true;
+ };
+
+ return with_new_scope(function(){
+ // process AST
+ var ret = w.with_walkers({
+ "function": _lambda,
+ "defun": _lambda,
+ "label": function(name, stat) { current_scope.labels.define(name) },
+ "break": _breacont,
+ "continue": _breacont,
+ "with": function(expr, block) {
+ for (var s = current_scope; s; s = s.parent)
+ s.uses_with = true;
+ },
+ "var": _vardefs("var"),
+ "const": _vardefs("const"),
+ "try": function(t, c, f) {
+ if (c != null) return [
+ this[0],
+ MAP(t, walk),
+ [ define(c[0], "catch"), MAP(c[1], walk) ],
+ f != null ? MAP(f, walk) : null
+ ];
+ },
+ "name": function(name) {
+ if (name == "eval")
+ having_eval.push(current_scope);
+ reference(name);
+ }
+ }, function(){
+ return walk(ast);
+ });
+
+ // the reason why we need an additional pass here is
+ // that names can be used prior to their definition.
+
+ // scopes where eval was detected and their parents
+ // are marked with uses_eval, unless they define the
+ // "eval" name.
+ MAP(having_eval, function(scope){
+ if (!scope.has("eval")) while (scope) {
+ scope.uses_eval = true;
+ scope = scope.parent;
+ }
+ });
+
+ // for referenced names it might be useful to know
+ // their origin scope. current_scope here is the
+ // toplevel one.
+ function fixrefs(scope, i) {
+ // do children first; order shouldn't matter
+ for (i = scope.children.length; --i >= 0;)
+ fixrefs(scope.children[i]);
+ for (i in scope.refs) if (HOP(scope.refs, i)) {
+ // find origin scope and propagate the reference to origin
+ for (var origin = scope.has(i), s = scope; s; s = s.parent) {
+ s.refs[i] = origin;
+ if (s === origin) break;
+ }
+ }
+ };
+ fixrefs(current_scope);
+
+ return ret;
+ });
+
+};
+
+/* -----[ mangle names ]----- */
+
+function ast_mangle(ast, options) {
+ var w = ast_walker(), walk = w.walk, scope;
+ options = defaults(options, {
+ mangle : true,
+ toplevel : false,
+ defines : null,
+ except : null,
+ no_functions : false
+ });
+
+ function get_mangled(name, newMangle) {
+ if (!options.mangle) return name;
+ if (!options.toplevel && !scope.parent) return name; // don't mangle toplevel
+ if (options.except && member(name, options.except))
+ return name;
+ if (options.no_functions && HOP(scope.names, name) &&
+ (scope.names[name] == 'defun' || scope.names[name] == 'lambda'))
+ return name;
+ return scope.get_mangled(name, newMangle);
+ };
+
+ function get_define(name) {
+ if (options.defines) {
+ // we always lookup a defined symbol for the current scope FIRST, so declared
+ // vars trump a DEFINE symbol, but if no such var is found, then match a DEFINE value
+ if (!scope.has(name)) {
+ if (HOP(options.defines, name)) {
+ return options.defines[name];
+ }
+ }
+ return null;
+ }
+ };
+
+ function _lambda(name, args, body) {
+ if (!options.no_functions && options.mangle) {
+ var is_defun = this[0] == "defun", extra;
+ if (name) {
+ if (is_defun) name = get_mangled(name);
+ else if (body.scope.references(name)) {
+ extra = {};
+ if (!(scope.uses_eval || scope.uses_with))
+ name = extra[name] = scope.next_mangled();
+ else
+ extra[name] = name;
+ }
+ else name = null;
+ }
+ }
+ body = with_scope(body.scope, function(){
+ args = MAP(args, function(name){ return get_mangled(name) });
+ return MAP(body, walk);
+ }, extra);
+ return [ this[0], name, args, body ];
+ };
+
+ function with_scope(s, cont, extra) {
+ var _scope = scope;
+ scope = s;
+ if (extra) for (var i in extra) if (HOP(extra, i)) {
+ s.set_mangle(i, extra[i]);
+ }
+ for (var i in s.names) if (HOP(s.names, i)) {
+ get_mangled(i, true);
+ }
+ var ret = cont();
+ ret.scope = s;
+ scope = _scope;
+ return ret;
+ };
+
+ function _vardefs(defs) {
+ return [ this[0], MAP(defs, function(d){
+ return [ get_mangled(d[0]), walk(d[1]) ];
+ }) ];
+ };
+
+ function _breacont(label) {
+ if (label) return [ this[0], scope.labels.get_mangled(label) ];
+ };
+
+ return w.with_walkers({
+ "function": _lambda,
+ "defun": function() {
+ // move function declarations to the top when
+ // they are not in some block.
+ var ast = _lambda.apply(this, arguments);
+ switch (w.parent()[0]) {
+ case "toplevel":
+ case "function":
+ case "defun":
+ return MAP.at_top(ast);
+ }
+ return ast;
+ },
+ "label": function(label, stat) {
+ if (scope.labels.refs[label]) return [
+ this[0],
+ scope.labels.get_mangled(label, true),
+ walk(stat)
+ ];
+ return walk(stat);
+ },
+ "break": _breacont,
+ "continue": _breacont,
+ "var": _vardefs,
+ "const": _vardefs,
+ "name": function(name) {
+ return get_define(name) || [ this[0], get_mangled(name) ];
+ },
+ "try": function(t, c, f) {
+ return [ this[0],
+ MAP(t, walk),
+ c != null ? [ get_mangled(c[0]), MAP(c[1], walk) ] : null,
+ f != null ? MAP(f, walk) : null ];
+ },
+ "toplevel": function(body) {
+ var self = this;
+ return with_scope(self.scope, function(){
+ return [ self[0], MAP(body, walk) ];
+ });
+ },
+ "directive": function() {
+ return MAP.at_top(this);
+ }
+ }, function() {
+ return walk(ast_add_scope(ast));
+ });
+};
+
+/* -----[
+ - compress foo["bar"] into foo.bar,
+ - remove block brackets {} where possible
+ - join consecutive var declarations
+ - various optimizations for IFs:
+ - if (cond) foo(); else bar(); ==> cond?foo():bar();
+ - if (cond) foo(); ==> cond&&foo();
+ - if (foo) return bar(); else return baz(); ==> return foo?bar():baz(); // also for throw
+ - if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}
+ ]----- */
+
+var warn = function(){};
+
+function best_of(ast1, ast2) {
+ return gen_code(ast1).length > gen_code(ast2[0] == "stat" ? ast2[1] : ast2).length ? ast2 : ast1;
+};
+
+function last_stat(b) {
+ if (b[0] == "block" && b[1] && b[1].length > 0)
+ return b[1][b[1].length - 1];
+ return b;
+}
+
+function aborts(t) {
+ if (t) switch (last_stat(t)[0]) {
+ case "return":
+ case "break":
+ case "continue":
+ case "throw":
+ return true;
+ }
+};
+
+function boolean_expr(expr) {
+ return ( (expr[0] == "unary-prefix"
+ && member(expr[1], [ "!", "delete" ])) ||
+
+ (expr[0] == "binary"
+ && member(expr[1], [ "in", "instanceof", "==", "!=", "===", "!==", "<", "<=", ">=", ">" ])) ||
+
+ (expr[0] == "binary"
+ && member(expr[1], [ "&&", "||" ])
+ && boolean_expr(expr[2])
+ && boolean_expr(expr[3])) ||
+
+ (expr[0] == "conditional"
+ && boolean_expr(expr[2])
+ && boolean_expr(expr[3])) ||
+
+ (expr[0] == "assign"
+ && expr[1] === true
+ && boolean_expr(expr[3])) ||
+
+ (expr[0] == "seq"
+ && boolean_expr(expr[expr.length - 1]))
+ );
+};
+
+function empty(b) {
+ return !b || (b[0] == "block" && (!b[1] || b[1].length == 0));
+};
+
+function is_string(node) {
+ return (node[0] == "string" ||
+ node[0] == "unary-prefix" && node[1] == "typeof" ||
+ node[0] == "binary" && node[1] == "+" &&
+ (is_string(node[2]) || is_string(node[3])));
+};
+
+var when_constant = (function(){
+
+ var $NOT_CONSTANT = {};
+
+ // this can only evaluate constant expressions. If it finds anything
+ // not constant, it throws $NOT_CONSTANT.
+ function evaluate(expr) {
+ switch (expr[0]) {
+ case "string":
+ case "num":
+ return expr[1];
+ case "name":
+ case "atom":
+ switch (expr[1]) {
+ case "true": return true;
+ case "false": return false;
+ case "null": return null;
+ }
+ break;
+ case "unary-prefix":
+ switch (expr[1]) {
+ case "!": return !evaluate(expr[2]);
+ case "typeof": return typeof evaluate(expr[2]);
+ case "~": return ~evaluate(expr[2]);
+ case "-": return -evaluate(expr[2]);
+ case "+": return +evaluate(expr[2]);
+ }
+ break;
+ case "binary":
+ var left = expr[2], right = expr[3];
+ switch (expr[1]) {
+ case "&&" : return evaluate(left) && evaluate(right);
+ case "||" : return evaluate(left) || evaluate(right);
+ case "|" : return evaluate(left) | evaluate(right);
+ case "&" : return evaluate(left) & evaluate(right);
+ case "^" : return evaluate(left) ^ evaluate(right);
+ case "+" : return evaluate(left) + evaluate(right);
+ case "*" : return evaluate(left) * evaluate(right);
+ case "/" : return evaluate(left) / evaluate(right);
+ case "%" : return evaluate(left) % evaluate(right);
+ case "-" : return evaluate(left) - evaluate(right);
+ case "<<" : return evaluate(left) << evaluate(right);
+ case ">>" : return evaluate(left) >> evaluate(right);
+ case ">>>" : return evaluate(left) >>> evaluate(right);
+ case "==" : return evaluate(left) == evaluate(right);
+ case "===" : return evaluate(left) === evaluate(right);
+ case "!=" : return evaluate(left) != evaluate(right);
+ case "!==" : return evaluate(left) !== evaluate(right);
+ case "<" : return evaluate(left) < evaluate(right);
+ case "<=" : return evaluate(left) <= evaluate(right);
+ case ">" : return evaluate(left) > evaluate(right);
+ case ">=" : return evaluate(left) >= evaluate(right);
+ case "in" : return evaluate(left) in evaluate(right);
+ case "instanceof" : return evaluate(left) instanceof evaluate(right);
+ }
+ }
+ throw $NOT_CONSTANT;
+ };
+
+ return function(expr, yes, no) {
+ try {
+ var val = evaluate(expr), ast;
+ switch (typeof val) {
+ case "string": ast = [ "string", val ]; break;
+ case "number": ast = [ "num", val ]; break;
+ case "boolean": ast = [ "name", String(val) ]; break;
+ default:
+ if (val === null) { ast = [ "atom", "null" ]; break; }
+ throw new Error("Can't handle constant of type: " + (typeof val));
+ }
+ return yes.call(expr, ast, val);
+ } catch(ex) {
+ if (ex === $NOT_CONSTANT) {
+ if (expr[0] == "binary"
+ && (expr[1] == "===" || expr[1] == "!==")
+ && ((is_string(expr[2]) && is_string(expr[3]))
+ || (boolean_expr(expr[2]) && boolean_expr(expr[3])))) {
+ expr[1] = expr[1].substr(0, 2);
+ }
+ else if (no && expr[0] == "binary"
+ && (expr[1] == "||" || expr[1] == "&&")) {
+ // the whole expression is not constant but the lval may be...
+ try {
+ var lval = evaluate(expr[2]);
+ expr = ((expr[1] == "&&" && (lval ? expr[3] : lval)) ||
+ (expr[1] == "||" && (lval ? lval : expr[3])) ||
+ expr);
+ } catch(ex2) {
+ // IGNORE... lval is not constant
+ }
+ }
+ return no ? no.call(expr, expr) : null;
+ }
+ else throw ex;
+ }
+ };
+
+})();
+
+function warn_unreachable(ast) {
+ if (!empty(ast))
+ warn("Dropping unreachable code: " + gen_code(ast, true));
+};
+
+function prepare_ifs(ast) {
+ var w = ast_walker(), walk = w.walk;
+ // In this first pass, we rewrite ifs which abort with no else with an
+ // if-else. For example:
+ //
+ // if (x) {
+ // blah();
+ // return y;
+ // }
+ // foobar();
+ //
+ // is rewritten into:
+ //
+ // if (x) {
+ // blah();
+ // return y;
+ // } else {
+ // foobar();
+ // }
+ function redo_if(statements) {
+ statements = MAP(statements, walk);
+
+ for (var i = 0; i < statements.length; ++i) {
+ var fi = statements[i];
+ if (fi[0] != "if") continue;
+
+ if (fi[3] && walk(fi[3])) continue;
+
+ var t = walk(fi[2]);
+ if (!aborts(t)) continue;
+
+ var conditional = walk(fi[1]);
+
+ var e_body = redo_if(statements.slice(i + 1));
+ var e = e_body.length == 1 ? e_body[0] : [ "block", e_body ];
+
+ return statements.slice(0, i).concat([ [
+ fi[0], // "if"
+ conditional, // conditional
+ t, // then
+ e // else
+ ] ]);
+ }
+
+ return statements;
+ };
+
+ function redo_if_lambda(name, args, body) {
+ body = redo_if(body);
+ return [ this[0], name, args, body ];
+ };
+
+ function redo_if_block(statements) {
+ return [ this[0], statements != null ? redo_if(statements) : null ];
+ };
+
+ return w.with_walkers({
+ "defun": redo_if_lambda,
+ "function": redo_if_lambda,
+ "block": redo_if_block,
+ "splice": redo_if_block,
+ "toplevel": function(statements) {
+ return [ this[0], redo_if(statements) ];
+ },
+ "try": function(t, c, f) {
+ return [
+ this[0],
+ redo_if(t),
+ c != null ? [ c[0], redo_if(c[1]) ] : null,
+ f != null ? redo_if(f) : null
+ ];
+ }
+ }, function() {
+ return walk(ast);
+ });
+};
+
+function for_side_effects(ast, handler) {
+ var w = ast_walker(), walk = w.walk;
+ var $stop = {}, $restart = {};
+ function stop() { throw $stop };
+ function restart() { throw $restart };
+ function found(){ return handler.call(this, this, w, stop, restart) };
+ function unary(op) {
+ if (op == "++" || op == "--")
+ return found.apply(this, arguments);
+ };
+ return w.with_walkers({
+ "try": found,
+ "throw": found,
+ "return": found,
+ "new": found,
+ "switch": found,
+ "break": found,
+ "continue": found,
+ "assign": found,
+ "call": found,
+ "if": found,
+ "for": found,
+ "for-in": found,
+ "while": found,
+ "do": found,
+ "return": found,
+ "unary-prefix": unary,
+ "unary-postfix": unary,
+ "defun": found
+ }, function(){
+ while (true) try {
+ walk(ast);
+ break;
+ } catch(ex) {
+ if (ex === $stop) break;
+ if (ex === $restart) continue;
+ throw ex;
+ }
+ });
+};
+
+function ast_lift_variables(ast) {
+ var w = ast_walker(), walk = w.walk, scope;
+ function do_body(body, env) {
+ var _scope = scope;
+ scope = env;
+ body = MAP(body, walk);
+ var hash = {}, names = MAP(env.names, function(type, name){
+ if (type != "var") return MAP.skip;
+ if (!env.references(name)) return MAP.skip;
+ hash[name] = true;
+ return [ name ];
+ });
+ if (names.length > 0) {
+ // looking for assignments to any of these variables.
+ // we can save considerable space by moving the definitions
+ // in the var declaration.
+ for_side_effects([ "block", body ], function(ast, walker, stop, restart) {
+ if (ast[0] == "assign"
+ && ast[1] === true
+ && ast[2][0] == "name"
+ && HOP(hash, ast[2][1])) {
+ // insert the definition into the var declaration
+ for (var i = names.length; --i >= 0;) {
+ if (names[i][0] == ast[2][1]) {
+ if (names[i][1]) // this name already defined, we must stop
+ stop();
+ names[i][1] = ast[3]; // definition
+ names.push(names.splice(i, 1)[0]);
+ break;
+ }
+ }
+ // remove this assignment from the AST.
+ var p = walker.parent();
+ if (p[0] == "seq") {
+ var a = p[2];
+ a.unshift(0, p.length);
+ p.splice.apply(p, a);
+ }
+ else if (p[0] == "stat") {
+ p.splice(0, p.length, "block"); // empty statement
+ }
+ else {
+ stop();
+ }
+ restart();
+ }
+ stop();
+ });
+ body.unshift([ "var", names ]);
+ }
+ scope = _scope;
+ return body;
+ };
+ function _vardefs(defs) {
+ var ret = null;
+ for (var i = defs.length; --i >= 0;) {
+ var d = defs[i];
+ if (!d[1]) continue;
+ d = [ "assign", true, [ "name", d[0] ], d[1] ];
+ if (ret == null) ret = d;
+ else ret = [ "seq", d, ret ];
+ }
+ if (ret == null) {
+ if (w.parent()[0] == "for-in")
+ return [ "name", defs[0][0] ];
+ return MAP.skip;
+ }
+ return [ "stat", ret ];
+ };
+ function _toplevel(body) {
+ return [ this[0], do_body(body, this.scope) ];
+ };
+ return w.with_walkers({
+ "function": function(name, args, body){
+ for (var i = args.length; --i >= 0 && !body.scope.references(args[i]);)
+ args.pop();
+ if (!body.scope.references(name)) name = null;
+ return [ this[0], name, args, do_body(body, body.scope) ];
+ },
+ "defun": function(name, args, body){
+ if (!scope.references(name)) return MAP.skip;
+ for (var i = args.length; --i >= 0 && !body.scope.references(args[i]);)
+ args.pop();
+ return [ this[0], name, args, do_body(body, body.scope) ];
+ },
+ "var": _vardefs,
+ "toplevel": _toplevel
+ }, function(){
+ return walk(ast_add_scope(ast));
+ });
+};
+
+function ast_squeeze(ast, options) {
+ options = defaults(options, {
+ make_seqs : true,
+ dead_code : true,
+ no_warnings : false,
+ keep_comps : true,
+ unsafe : false
+ });
+
+ var w = ast_walker(), walk = w.walk, scope;
+
+ function negate(c) {
+ var not_c = [ "unary-prefix", "!", c ];
+ switch (c[0]) {
+ case "unary-prefix":
+ return c[1] == "!" && boolean_expr(c[2]) ? c[2] : not_c;
+ case "seq":
+ c = slice(c);
+ c[c.length - 1] = negate(c[c.length - 1]);
+ return c;
+ case "conditional":
+ return best_of(not_c, [ "conditional", c[1], negate(c[2]), negate(c[3]) ]);
+ case "binary":
+ var op = c[1], left = c[2], right = c[3];
+ if (!options.keep_comps) switch (op) {
+ case "<=" : return [ "binary", ">", left, right ];
+ case "<" : return [ "binary", ">=", left, right ];
+ case ">=" : return [ "binary", "<", left, right ];
+ case ">" : return [ "binary", "<=", left, right ];
+ }
+ switch (op) {
+ case "==" : return [ "binary", "!=", left, right ];
+ case "!=" : return [ "binary", "==", left, right ];
+ case "===" : return [ "binary", "!==", left, right ];
+ case "!==" : return [ "binary", "===", left, right ];
+ case "&&" : return best_of(not_c, [ "binary", "||", negate(left), negate(right) ]);
+ case "||" : return best_of(not_c, [ "binary", "&&", negate(left), negate(right) ]);
+ }
+ break;
+ }
+ return not_c;
+ };
+
+ function make_conditional(c, t, e) {
+ var make_real_conditional = function() {
+ if (c[0] == "unary-prefix" && c[1] == "!") {
+ return e ? [ "conditional", c[2], e, t ] : [ "binary", "||", c[2], t ];
+ } else {
+ return e ? best_of(
+ [ "conditional", c, t, e ],
+ [ "conditional", negate(c), e, t ]
+ ) : [ "binary", "&&", c, t ];
+ }
+ };
+ // shortcut the conditional if the expression has a constant value
+ return when_constant(c, function(ast, val){
+ warn_unreachable(val ? e : t);
+ return (val ? t : e);
+ }, make_real_conditional);
+ };
+
+ function rmblock(block) {
+ if (block != null && block[0] == "block" && block[1]) {
+ if (block[1].length == 1)
+ block = block[1][0];
+ else if (block[1].length == 0)
+ block = [ "block" ];
+ }
+ return block;
+ };
+
+ function _lambda(name, args, body) {
+ return [ this[0], name, args, with_scope(body.scope, function() {
+ return tighten(body, "lambda");
+ }) ];
+ };
+
+ function with_scope(s, cont) {
+ var _scope = scope;
+ scope = s;
+ var ret = cont();
+ scope = _scope;
+ return ret;
+ };
+
+ // this function does a few things:
+ // 1. discard useless blocks
+ // 2. join consecutive var declarations
+ // 3. remove obviously dead code
+ // 4. transform consecutive statements using the comma operator
+ // 5. if block_type == "lambda" and it detects constructs like if(foo) return ... - rewrite like if (!foo) { ... }
+ function tighten(statements, block_type) {
+ statements = MAP(statements, walk);
+
+ statements = statements.reduce(function(a, stat){
+ if (stat[0] == "block") {
+ if (stat[1]) {
+ a.push.apply(a, stat[1]);
+ }
+ } else {
+ a.push(stat);
+ }
+ return a;
+ }, []);
+
+ statements = (function(a, prev){
+ statements.forEach(function(cur){
+ if (prev && ((cur[0] == "var" && prev[0] == "var") ||
+ (cur[0] == "const" && prev[0] == "const"))) {
+ prev[1] = prev[1].concat(cur[1]);
+ } else {
+ a.push(cur);
+ prev = cur;
+ }
+ });
+ return a;
+ })([]);
+
+ if (options.dead_code) statements = (function(a, has_quit){
+ statements.forEach(function(st){
+ if (has_quit) {
+ if (st[0] == "function" || st[0] == "defun") {
+ a.push(st);
+ }
+ else if (st[0] == "var" || st[0] == "const") {
+ if (!options.no_warnings)
+ warn("Variables declared in unreachable code");
+ st[1] = MAP(st[1], function(def){
+ if (def[1] && !options.no_warnings)
+ warn_unreachable([ "assign", true, [ "name", def[0] ], def[1] ]);
+ return [ def[0] ];
+ });
+ a.push(st);
+ }
+ else if (!options.no_warnings)
+ warn_unreachable(st);
+ }
+ else {
+ a.push(st);
+ if (member(st[0], [ "return", "throw", "break", "continue" ]))
+ has_quit = true;
+ }
+ });
+ return a;
+ })([]);
+
+ if (options.make_seqs) statements = (function(a, prev) {
+ statements.forEach(function(cur){
+ if (prev && prev[0] == "stat" && cur[0] == "stat") {
+ prev[1] = [ "seq", prev[1], cur[1] ];
+ } else {
+ a.push(cur);
+ prev = cur;
+ }
+ });
+ if (a.length >= 2
+ && a[a.length-2][0] == "stat"
+ && (a[a.length-1][0] == "return" || a[a.length-1][0] == "throw")
+ && a[a.length-1][1])
+ {
+ a.splice(a.length - 2, 2,
+ [ a[a.length-1][0],
+ [ "seq", a[a.length-2][1], a[a.length-1][1] ]]);
+ }
+ return a;
+ })([]);
+
+ // this increases jQuery by 1K. Probably not such a good idea after all..
+ // part of this is done in prepare_ifs anyway.
+ // if (block_type == "lambda") statements = (function(i, a, stat){
+ // while (i < statements.length) {
+ // stat = statements[i++];
+ // if (stat[0] == "if" && !stat[3]) {
+ // if (stat[2][0] == "return" && stat[2][1] == null) {
+ // a.push(make_if(negate(stat[1]), [ "block", statements.slice(i) ]));
+ // break;
+ // }
+ // var last = last_stat(stat[2]);
+ // if (last[0] == "return" && last[1] == null) {
+ // a.push(make_if(stat[1], [ "block", stat[2][1].slice(0, -1) ], [ "block", statements.slice(i) ]));
+ // break;
+ // }
+ // }
+ // a.push(stat);
+ // }
+ // return a;
+ // })(0, []);
+
+ return statements;
+ };
+
+ function make_if(c, t, e) {
+ return when_constant(c, function(ast, val){
+ if (val) {
+ t = walk(t);
+ warn_unreachable(e);
+ return t || [ "block" ];
+ } else {
+ e = walk(e);
+ warn_unreachable(t);
+ return e || [ "block" ];
+ }
+ }, function() {
+ return make_real_if(c, t, e);
+ });
+ };
+
+ function abort_else(c, t, e) {
+ var ret = [ [ "if", negate(c), e ] ];
+ if (t[0] == "block") {
+ if (t[1]) ret = ret.concat(t[1]);
+ } else {
+ ret.push(t);
+ }
+ return walk([ "block", ret ]);
+ };
+
+ function make_real_if(c, t, e) {
+ c = walk(c);
+ t = walk(t);
+ e = walk(e);
+
+ if (empty(e) && empty(t))
+ return [ "stat", c ];
+
+ if (empty(t)) {
+ c = negate(c);
+ t = e;
+ e = null;
+ } else if (empty(e)) {
+ e = null;
+ } else {
+ // if we have both else and then, maybe it makes sense to switch them?
+ (function(){
+ var a = gen_code(c);
+ var n = negate(c);
+ var b = gen_code(n);
+ if (b.length < a.length) {
+ var tmp = t;
+ t = e;
+ e = tmp;
+ c = n;
+ }
+ })();
+ }
+ var ret = [ "if", c, t, e ];
+ if (t[0] == "if" && empty(t[3]) && empty(e)) {
+ ret = best_of(ret, walk([ "if", [ "binary", "&&", c, t[1] ], t[2] ]));
+ }
+ else if (t[0] == "stat") {
+ if (e) {
+ if (e[0] == "stat")
+ ret = best_of(ret, [ "stat", make_conditional(c, t[1], e[1]) ]);
+ else if (aborts(e))
+ ret = abort_else(c, t, e);
+ }
+ else {
+ ret = best_of(ret, [ "stat", make_conditional(c, t[1]) ]);
+ }
+ }
+ else if (e && t[0] == e[0] && (t[0] == "return" || t[0] == "throw") && t[1] && e[1]) {
+ ret = best_of(ret, [ t[0], make_conditional(c, t[1], e[1] ) ]);
+ }
+ else if (e && aborts(t)) {
+ ret = [ [ "if", c, t ] ];
+ if (e[0] == "block") {
+ if (e[1]) ret = ret.concat(e[1]);
+ }
+ else {
+ ret.push(e);
+ }
+ ret = walk([ "block", ret ]);
+ }
+ else if (t && aborts(e)) {
+ ret = abort_else(c, t, e);
+ }
+ return ret;
+ };
+
+ function _do_while(cond, body) {
+ return when_constant(cond, function(cond, val){
+ if (!val) {
+ warn_unreachable(body);
+ return [ "block" ];
+ } else {
+ return [ "for", null, null, null, walk(body) ];
+ }
+ });
+ };
+
+ return w.with_walkers({
+ "sub": function(expr, subscript) {
+ if (subscript[0] == "string") {
+ var name = subscript[1];
+ if (is_identifier(name))
+ return [ "dot", walk(expr), name ];
+ else if (/^[1-9][0-9]*$/.test(name) || name === "0")
+ return [ "sub", walk(expr), [ "num", parseInt(name, 10) ] ];
+ }
+ },
+ "if": make_if,
+ "toplevel": function(body) {
+ return with_scope(this.scope, function() {
+ return [ "toplevel", tighten(body) ];
+ });
+ },
+ "switch": function(expr, body) {
+ var last = body.length - 1;
+ return [ "switch", walk(expr), MAP(body, function(branch, i){
+ var block = tighten(branch[1]);
+ if (i == last && block.length > 0) {
+ var node = block[block.length - 1];
+ if (node[0] == "break" && !node[1])
+ block.pop();
+ }
+ return [ branch[0] ? walk(branch[0]) : null, block ];
+ }) ];
+ },
+ "function": _lambda,
+ "defun": _lambda,
+ "block": function(body) {
+ if (body) return rmblock([ "block", tighten(body) ]);
+ },
+ "binary": function(op, left, right) {
+ return when_constant([ "binary", op, walk(left), walk(right) ], function yes(c){
+ return best_of(walk(c), this);
+ }, function no() {
+ return function(){
+ if(op != "==" && op != "!=") return;
+ var l = walk(left), r = walk(right);
+ if(l && l[0] == "unary-prefix" && l[1] == "!" && l[2][0] == "num")
+ left = ['num', +!l[2][1]];
+ else if (r && r[0] == "unary-prefix" && r[1] == "!" && r[2][0] == "num")
+ right = ['num', +!r[2][1]];
+ return ["binary", op, left, right];
+ }() || this;
+ });
+ },
+ "conditional": function(c, t, e) {
+ return make_conditional(walk(c), walk(t), walk(e));
+ },
+ "try": function(t, c, f) {
+ return [
+ "try",
+ tighten(t),
+ c != null ? [ c[0], tighten(c[1]) ] : null,
+ f != null ? tighten(f) : null
+ ];
+ },
+ "unary-prefix": function(op, expr) {
+ expr = walk(expr);
+ var ret = [ "unary-prefix", op, expr ];
+ if (op == "!")
+ ret = best_of(ret, negate(expr));
+ return when_constant(ret, function(ast, val){
+ return walk(ast); // it's either true or false, so minifies to !0 or !1
+ }, function() { return ret });
+ },
+ "name": function(name) {
+ switch (name) {
+ case "true": return [ "unary-prefix", "!", [ "num", 0 ]];
+ case "false": return [ "unary-prefix", "!", [ "num", 1 ]];
+ }
+ },
+ "while": _do_while,
+ "assign": function(op, lvalue, rvalue) {
+ lvalue = walk(lvalue);
+ rvalue = walk(rvalue);
+ var okOps = [ '+', '-', '/', '*', '%', '>>', '<<', '>>>', '|', '^', '&' ];
+ if (op === true && lvalue[0] === "name" && rvalue[0] === "binary" &&
+ ~okOps.indexOf(rvalue[1]) && rvalue[2][0] === "name" &&
+ rvalue[2][1] === lvalue[1]) {
+ return [ this[0], rvalue[1], lvalue, rvalue[3] ]
+ }
+ return [ this[0], op, lvalue, rvalue ];
+ },
+ "directive": function(dir) {
+ if (scope.active(dir))
+ return [ "block" ];
+ scope.directives.push(dir);
+ return [ this[0], dir ];
+ },
+ "call": function(expr, args) {
+ expr = walk(expr);
+ if (options.unsafe && expr[0] == "dot" && expr[1][0] == "string" && expr[2] == "toString") {
+ return expr[1];
+ }
+ return [ this[0], expr, MAP(args, walk) ];
+ },
+ "num": function (num) {
+ if (!isFinite(num))
+ return [ "binary", "/", num === 1 / 0
+ ? [ "num", 1 ] : num === -1 / 0
+ ? [ "unary-prefix", "-", [ "num", 1 ] ]
+ : [ "num", 0 ], [ "num", 0 ] ];
+
+ return [ this[0], num ];
+ }
+ }, function() {
+ for (var i = 0; i < 2; ++i) {
+ ast = prepare_ifs(ast);
+ ast = walk(ast_add_scope(ast));
+ }
+ return ast;
+ });
+};
+
+/* -----[ re-generate code from the AST ]----- */
+
+var DOT_CALL_NO_PARENS = jsp.array_to_hash([
+ "name",
+ "array",
+ "object",
+ "string",
+ "dot",
+ "sub",
+ "call",
+ "regexp",
+ "defun"
+]);
+
+function make_string(str, ascii_only) {
+ var dq = 0, sq = 0;
+ str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029\0]/g, function(s){
+ switch (s) {
+ case "\\": return "\\\\";
+ case "\b": return "\\b";
+ case "\f": return "\\f";
+ case "\n": return "\\n";
+ case "\r": return "\\r";
+ case "\u2028": return "\\u2028";
+ case "\u2029": return "\\u2029";
+ case '"': ++dq; return '"';
+ case "'": ++sq; return "'";
+ case "\0": return "\\0";
+ }
+ return s;
+ });
+ if (ascii_only) str = to_ascii(str);
+ if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'";
+ else return '"' + str.replace(/\x22/g, '\\"') + '"';
+};
+
+function to_ascii(str) {
+ return str.replace(/[\u0080-\uffff]/g, function(ch) {
+ var code = ch.charCodeAt(0).toString(16);
+ while (code.length < 4) code = "0" + code;
+ return "\\u" + code;
+ });
+};
+
+var SPLICE_NEEDS_BRACKETS = jsp.array_to_hash([ "if", "while", "do", "for", "for-in", "with" ]);
+
+function gen_code(ast, options) {
+ options = defaults(options, {
+ indent_start : 0,
+ indent_level : 4,
+ quote_keys : false,
+ space_colon : false,
+ beautify : false,
+ ascii_only : false,
+ inline_script: false
+ });
+ var beautify = !!options.beautify;
+ var indentation = 0,
+ newline = beautify ? "\n" : "",
+ space = beautify ? " " : "";
+
+ function encode_string(str) {
+ var ret = make_string(str, options.ascii_only);
+ if (options.inline_script)
+ ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1");
+ return ret;
+ };
+
+ function make_name(name) {
+ name = name.toString();
+ if (options.ascii_only)
+ name = to_ascii(name);
+ return name;
+ };
+
+ function indent(line) {
+ if (line == null)
+ line = "";
+ if (beautify)
+ line = repeat_string(" ", options.indent_start + indentation * options.indent_level) + line;
+ return line;
+ };
+
+ function with_indent(cont, incr) {
+ if (incr == null) incr = 1;
+ indentation += incr;
+ try { return cont.apply(null, slice(arguments, 1)); }
+ finally { indentation -= incr; }
+ };
+
+ function last_char(str) {
+ str = str.toString();
+ return str.charAt(str.length - 1);
+ };
+
+ function first_char(str) {
+ return str.toString().charAt(0);
+ };
+
+ function add_spaces(a) {
+ if (beautify)
+ return a.join(" ");
+ var b = [];
+ for (var i = 0; i < a.length; ++i) {
+ var next = a[i + 1];
+ b.push(a[i]);
+ if (next &&
+ ((is_identifier_char(last_char(a[i])) && (is_identifier_char(first_char(next))
+ || first_char(next) == "\\")) ||
+ (/[\+\-]$/.test(a[i].toString()) && /^[\+\-]/.test(next.toString())))) {
+ b.push(" ");
+ }
+ }
+ return b.join("");
+ };
+
+ function add_commas(a) {
+ return a.join("," + space);
+ };
+
+ function parenthesize(expr) {
+ var gen = make(expr);
+ for (var i = 1; i < arguments.length; ++i) {
+ var el = arguments[i];
+ if ((el instanceof Function && el(expr)) || expr[0] == el)
+ return "(" + gen + ")";
+ }
+ return gen;
+ };
+
+ function best_of(a) {
+ if (a.length == 1) {
+ return a[0];
+ }
+ if (a.length == 2) {
+ var b = a[1];
+ a = a[0];
+ return a.length <= b.length ? a : b;
+ }
+ return best_of([ a[0], best_of(a.slice(1)) ]);
+ };
+
+ function needs_parens(expr) {
+ if (expr[0] == "function" || expr[0] == "object") {
+ // dot/call on a literal function requires the
+ // function literal itself to be parenthesized
+ // only if it's the first "thing" in a
+ // statement. This means that the parent is
+ // "stat", but it could also be a "seq" and
+ // we're the first in this "seq" and the
+ // parent is "stat", and so on. Messy stuff,
+ // but it worths the trouble.
+ var a = slice(w.stack()), self = a.pop(), p = a.pop();
+ while (p) {
+ if (p[0] == "stat") return true;
+ if (((p[0] == "seq" || p[0] == "call" || p[0] == "dot" || p[0] == "sub" || p[0] == "conditional") && p[1] === self) ||
+ ((p[0] == "binary" || p[0] == "assign" || p[0] == "unary-postfix") && p[2] === self)) {
+ self = p;
+ p = a.pop();
+ } else {
+ return false;
+ }
+ }
+ }
+ return !HOP(DOT_CALL_NO_PARENS, expr[0]);
+ };
+
+ function make_num(num) {
+ var str = num.toString(10), a = [ str.replace(/^0\./, ".").replace('e+', 'e') ], m;
+ if (Math.floor(num) === num) {
+ if (num >= 0) {
+ a.push("0x" + num.toString(16).toLowerCase(), // probably pointless
+ "0" + num.toString(8)); // same.
+ } else {
+ a.push("-0x" + (-num).toString(16).toLowerCase(), // probably pointless
+ "-0" + (-num).toString(8)); // same.
+ }
+ if ((m = /^(.*?)(0+)$/.exec(num))) {
+ a.push(m[1] + "e" + m[2].length);
+ }
+ } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) {
+ a.push(m[2] + "e-" + (m[1].length + m[2].length),
+ str.substr(str.indexOf(".")));
+ }
+ return best_of(a);
+ };
+
+ var w = ast_walker();
+ var make = w.walk;
+ return w.with_walkers({
+ "string": encode_string,
+ "num": make_num,
+ "name": make_name,
+ "debugger": function(){ return "debugger;" },
+ "toplevel": function(statements) {
+ return make_block_statements(statements)
+ .join(newline + newline);
+ },
+ "splice": function(statements) {
+ var parent = w.parent();
+ if (HOP(SPLICE_NEEDS_BRACKETS, parent)) {
+ // we need block brackets in this case
+ return make_block.apply(this, arguments);
+ } else {
+ return MAP(make_block_statements(statements, true),
+ function(line, i) {
+ // the first line is already indented
+ return i > 0 ? indent(line) : line;
+ }).join(newline);
+ }
+ },
+ "block": make_block,
+ "var": function(defs) {
+ return "var " + add_commas(MAP(defs, make_1vardef)) + ";";
+ },
+ "const": function(defs) {
+ return "const " + add_commas(MAP(defs, make_1vardef)) + ";";
+ },
+ "try": function(tr, ca, fi) {
+ var out = [ "try", make_block(tr) ];
+ if (ca) out.push("catch", "(" + ca[0] + ")", make_block(ca[1]));
+ if (fi) out.push("finally", make_block(fi));
+ return add_spaces(out);
+ },
+ "throw": function(expr) {
+ return add_spaces([ "throw", make(expr) ]) + ";";
+ },
+ "new": function(ctor, args) {
+ args = args.length > 0 ? "(" + add_commas(MAP(args, function(expr){
+ return parenthesize(expr, "seq");
+ })) + ")" : "";
+ return add_spaces([ "new", parenthesize(ctor, "seq", "binary", "conditional", "assign", function(expr){
+ var w = ast_walker(), has_call = {};
+ try {
+ w.with_walkers({
+ "call": function() { throw has_call },
+ "function": function() { return this }
+ }, function(){
+ w.walk(expr);
+ });
+ } catch(ex) {
+ if (ex === has_call)
+ return true;
+ throw ex;
+ }
+ }) + args ]);
+ },
+ "switch": function(expr, body) {
+ return add_spaces([ "switch", "(" + make(expr) + ")", make_switch_block(body) ]);
+ },
+ "break": function(label) {
+ var out = "break";
+ if (label != null)
+ out += " " + make_name(label);
+ return out + ";";
+ },
+ "continue": function(label) {
+ var out = "continue";
+ if (label != null)
+ out += " " + make_name(label);
+ return out + ";";
+ },
+ "conditional": function(co, th, el) {
+ return add_spaces([ parenthesize(co, "assign", "seq", "conditional"), "?",
+ parenthesize(th, "seq"), ":",
+ parenthesize(el, "seq") ]);
+ },
+ "assign": function(op, lvalue, rvalue) {
+ if (op && op !== true) op += "=";
+ else op = "=";
+ return add_spaces([ make(lvalue), op, parenthesize(rvalue, "seq") ]);
+ },
+ "dot": function(expr) {
+ var out = make(expr), i = 1;
+ if (expr[0] == "num") {
+ if (!/[a-f.]/i.test(out))
+ out += ".";
+ } else if (expr[0] != "function" && needs_parens(expr))
+ out = "(" + out + ")";
+ while (i < arguments.length)
+ out += "." + make_name(arguments[i++]);
+ return out;
+ },
+ "call": function(func, args) {
+ var f = make(func);
+ if (f.charAt(0) != "(" && needs_parens(func))
+ f = "(" + f + ")";
+ return f + "(" + add_commas(MAP(args, function(expr){
+ return parenthesize(expr, "seq");
+ })) + ")";
+ },
+ "function": make_function,
+ "defun": make_function,
+ "if": function(co, th, el) {
+ var out = [ "if", "(" + make(co) + ")", el ? make_then(th) : make(th) ];
+ if (el) {
+ out.push("else", make(el));
+ }
+ return add_spaces(out);
+ },
+ "for": function(init, cond, step, block) {
+ var out = [ "for" ];
+ init = (init != null ? make(init) : "").replace(/;*\s*$/, ";" + space);
+ cond = (cond != null ? make(cond) : "").replace(/;*\s*$/, ";" + space);
+ step = (step != null ? make(step) : "").replace(/;*\s*$/, "");
+ var args = init + cond + step;
+ if (args == "; ; ") args = ";;";
+ out.push("(" + args + ")", make(block));
+ return add_spaces(out);
+ },
+ "for-in": function(vvar, key, hash, block) {
+ return add_spaces([ "for", "(" +
+ (vvar ? make(vvar).replace(/;+$/, "") : make(key)),
+ "in",
+ make(hash) + ")", make(block) ]);
+ },
+ "while": function(condition, block) {
+ return add_spaces([ "while", "(" + make(condition) + ")", make(block) ]);
+ },
+ "do": function(condition, block) {
+ return add_spaces([ "do", make(block), "while", "(" + make(condition) + ")" ]) + ";";
+ },
+ "return": function(expr) {
+ var out = [ "return" ];
+ if (expr != null) out.push(make(expr));
+ return add_spaces(out) + ";";
+ },
+ "binary": function(operator, lvalue, rvalue) {
+ var left = make(lvalue), right = make(rvalue);
+ // XXX: I'm pretty sure other cases will bite here.
+ // we need to be smarter.
+ // adding parens all the time is the safest bet.
+ if (member(lvalue[0], [ "assign", "conditional", "seq" ]) ||
+ lvalue[0] == "binary" && PRECEDENCE[operator] > PRECEDENCE[lvalue[1]] ||
+ lvalue[0] == "function" && needs_parens(this)) {
+ left = "(" + left + ")";
+ }
+ if (member(rvalue[0], [ "assign", "conditional", "seq" ]) ||
+ rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]] &&
+ !(rvalue[1] == operator && member(operator, [ "&&", "||", "*" ]))) {
+ right = "(" + right + ")";
+ }
+ else if (!beautify && options.inline_script && (operator == "<" || operator == "<<")
+ && rvalue[0] == "regexp" && /^script/i.test(rvalue[1])) {
+ right = " " + right;
+ }
+ return add_spaces([ left, operator, right ]);
+ },
+ "unary-prefix": function(operator, expr) {
+ var val = make(expr);
+ if (!(expr[0] == "num" || (expr[0] == "unary-prefix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
+ val = "(" + val + ")";
+ return operator + (jsp.is_alphanumeric_char(operator.charAt(0)) ? " " : "") + val;
+ },
+ "unary-postfix": function(operator, expr) {
+ var val = make(expr);
+ if (!(expr[0] == "num" || (expr[0] == "unary-postfix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
+ val = "(" + val + ")";
+ return val + operator;
+ },
+ "sub": function(expr, subscript) {
+ var hash = make(expr);
+ if (needs_parens(expr))
+ hash = "(" + hash + ")";
+ return hash + "[" + make(subscript) + "]";
+ },
+ "object": function(props) {
+ var obj_needs_parens = needs_parens(this);
+ if (props.length == 0)
+ return obj_needs_parens ? "({})" : "{}";
+ var out = "{" + newline + with_indent(function(){
+ return MAP(props, function(p){
+ if (p.length == 3) {
+ // getter/setter. The name is in p[0], the arg.list in p[1][2], the
+ // body in p[1][3] and type ("get" / "set") in p[2].
+ return indent(make_function(p[0], p[1][2], p[1][3], p[2], true));
+ }
+ var key = p[0], val = parenthesize(p[1], "seq");
+ if (options.quote_keys) {
+ key = encode_string(key);
+ } else if ((typeof key == "number" || !beautify && +key + "" == key)
+ && parseFloat(key) >= 0) {
+ key = make_num(+key);
+ } else if (!is_identifier(key)) {
+ key = encode_string(key);
+ }
+ return indent(add_spaces(beautify && options.space_colon
+ ? [ key, ":", val ]
+ : [ key + ":", val ]));
+ }).join("," + newline);
+ }) + newline + indent("}");
+ return obj_needs_parens ? "(" + out + ")" : out;
+ },
+ "regexp": function(rx, mods) {
+ if (options.ascii_only) rx = to_ascii(rx);
+ return "/" + rx + "/" + mods;
+ },
+ "array": function(elements) {
+ if (elements.length == 0) return "[]";
+ return add_spaces([ "[", add_commas(MAP(elements, function(el, i){
+ if (!beautify && el[0] == "atom" && el[1] == "undefined") return i === elements.length - 1 ? "," : "";
+ return parenthesize(el, "seq");
+ })), "]" ]);
+ },
+ "stat": function(stmt) {
+ return make(stmt).replace(/;*\s*$/, ";");
+ },
+ "seq": function() {
+ return add_commas(MAP(slice(arguments), make));
+ },
+ "label": function(name, block) {
+ return add_spaces([ make_name(name), ":", make(block) ]);
+ },
+ "with": function(expr, block) {
+ return add_spaces([ "with", "(" + make(expr) + ")", make(block) ]);
+ },
+ "atom": function(name) {
+ return make_name(name);
+ },
+ "directive": function(dir) {
+ return make_string(dir) + ";";
+ }
+ }, function(){ return make(ast) });
+
+ // The squeezer replaces "block"-s that contain only a single
+ // statement with the statement itself; technically, the AST
+ // is correct, but this can create problems when we output an
+ // IF having an ELSE clause where the THEN clause ends in an
+ // IF *without* an ELSE block (then the outer ELSE would refer
+ // to the inner IF). This function checks for this case and
+ // adds the block brackets if needed.
+ function make_then(th) {
+ if (th == null) return ";";
+ if (th[0] == "do") {
+ // https://github.com/mishoo/UglifyJS/issues/#issue/57
+ // IE croaks with "syntax error" on code like this:
+ // if (foo) do ... while(cond); else ...
+ // we need block brackets around do/while
+ return make_block([ th ]);
+ }
+ var b = th;
+ while (true) {
+ var type = b[0];
+ if (type == "if") {
+ if (!b[3])
+ // no else, we must add the block
+ return make([ "block", [ th ]]);
+ b = b[3];
+ }
+ else if (type == "while" || type == "do") b = b[2];
+ else if (type == "for" || type == "for-in") b = b[4];
+ else break;
+ }
+ return make(th);
+ };
+
+ function make_function(name, args, body, keyword, no_parens) {
+ var out = keyword || "function";
+ if (name) {
+ out += " " + make_name(name);
+ }
+ out += "(" + add_commas(MAP(args, make_name)) + ")";
+ out = add_spaces([ out, make_block(body) ]);
+ return (!no_parens && needs_parens(this)) ? "(" + out + ")" : out;
+ };
+
+ function must_has_semicolon(node) {
+ switch (node[0]) {
+ case "with":
+ case "while":
+ return empty(node[2]) || must_has_semicolon(node[2]);
+ case "for":
+ case "for-in":
+ return empty(node[4]) || must_has_semicolon(node[4]);
+ case "if":
+ if (empty(node[2]) && !node[3]) return true; // `if' with empty `then' and no `else'
+ if (node[3]) {
+ if (empty(node[3])) return true; // `else' present but empty
+ return must_has_semicolon(node[3]); // dive into the `else' branch
+ }
+ return must_has_semicolon(node[2]); // dive into the `then' branch
+ case "directive":
+ return true;
+ }
+ };
+
+ function make_block_statements(statements, noindent) {
+ for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) {
+ var stat = statements[i];
+ var code = make(stat);
+ if (code != ";") {
+ if (!beautify && i == last && !must_has_semicolon(stat)) {
+ code = code.replace(/;+\s*$/, "");
+ }
+ a.push(code);
+ }
+ }
+ return noindent ? a : MAP(a, indent);
+ };
+
+ function make_switch_block(body) {
+ var n = body.length;
+ if (n == 0) return "{}";
+ return "{" + newline + MAP(body, function(branch, i){
+ var has_body = branch[1].length > 0, code = with_indent(function(){
+ return indent(branch[0]
+ ? add_spaces([ "case", make(branch[0]) + ":" ])
+ : "default:");
+ }, 0.5) + (has_body ? newline + with_indent(function(){
+ return make_block_statements(branch[1]).join(newline);
+ }) : "");
+ if (!beautify && has_body && i < n - 1)
+ code += ";";
+ return code;
+ }).join(newline) + newline + indent("}");
+ };
+
+ function make_block(statements) {
+ if (!statements) return ";";
+ if (statements.length == 0) return "{}";
+ return "{" + newline + with_indent(function(){
+ return make_block_statements(statements).join(newline);
+ }) + newline + indent("}");
+ };
+
+ function make_1vardef(def) {
+ var name = def[0], val = def[1];
+ if (val != null)
+ name = add_spaces([ make_name(name), "=", parenthesize(val, "seq") ]);
+ return name;
+ };
+
+};
+
+function split_lines(code, max_line_length) {
+ var splits = [ 0 ];
+ jsp.parse(function(){
+ var next_token = jsp.tokenizer(code);
+ var last_split = 0;
+ var prev_token;
+ function current_length(tok) {
+ return tok.pos - last_split;
+ };
+ function split_here(tok) {
+ last_split = tok.pos;
+ splits.push(last_split);
+ };
+ function custom(){
+ var tok = next_token.apply(this, arguments);
+ out: {
+ if (prev_token) {
+ if (prev_token.type == "keyword") break out;
+ }
+ if (current_length(tok) > max_line_length) {
+ switch (tok.type) {
+ case "keyword":
+ case "atom":
+ case "name":
+ case "punc":
+ split_here(tok);
+ break out;
+ }
+ }
+ }
+ prev_token = tok;
+ return tok;
+ };
+ custom.context = function() {
+ return next_token.context.apply(this, arguments);
+ };
+ return custom;
+ }());
+ return splits.map(function(pos, i){
+ return code.substring(pos, splits[i + 1] || code.length);
+ }).join("\n");
+};
+
+/* -----[ Utilities ]----- */
+
+function repeat_string(str, i) {
+ if (i <= 0) return "";
+ if (i == 1) return str;
+ var d = repeat_string(str, i >> 1);
+ d += d;
+ if (i & 1) d += str;
+ return d;
+};
+
+function defaults(args, defs) {
+ var ret = {};
+ if (args === true)
+ args = {};
+ for (var i in defs) if (HOP(defs, i)) {
+ ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
+ }
+ return ret;
+};
+
+function is_identifier(name) {
+ return /^[a-z_$][a-z0-9_$]*$/i.test(name)
+ && name != "this"
+ && !HOP(jsp.KEYWORDS_ATOM, name)
+ && !HOP(jsp.RESERVED_WORDS, name)
+ && !HOP(jsp.KEYWORDS, name);
+};
+
+function HOP(obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop);
+};
+
+// some utilities
+
+var MAP;
+
+(function(){
+ MAP = function(a, f, o) {
+ var ret = [], top = [], i;
+ function doit() {
+ var val = f.call(o, a[i], i);
+ if (val instanceof AtTop) {
+ val = val.v;
+ if (val instanceof Splice) {
+ top.push.apply(top, val.v);
+ } else {
+ top.push(val);
+ }
+ }
+ else if (val != skip) {
+ if (val instanceof Splice) {
+ ret.push.apply(ret, val.v);
+ } else {
+ ret.push(val);
+ }
+ }
+ };
+ if (a instanceof Array) for (i = 0; i < a.length; ++i) doit();
+ else for (i in a) if (HOP(a, i)) doit();
+ return top.concat(ret);
+ };
+ MAP.at_top = function(val) { return new AtTop(val) };
+ MAP.splice = function(val) { return new Splice(val) };
+ var skip = MAP.skip = {};
+ function AtTop(val) { this.v = val };
+ function Splice(val) { this.v = val };
+})();
+
+/* -----[ Exports ]----- */
+
+exports.ast_walker = ast_walker;
+exports.ast_mangle = ast_mangle;
+exports.ast_squeeze = ast_squeeze;
+exports.ast_lift_variables = ast_lift_variables;
+exports.gen_code = gen_code;
+exports.ast_add_scope = ast_add_scope;
+exports.set_logger = function(logger) { warn = logger };
+exports.make_string = make_string;
+exports.split_lines = split_lines;
+exports.MAP = MAP;
+
+// keep this last!
+exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more;
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjslibsqueezemorejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/squeeze-more.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/squeeze-more.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/lib/squeeze-more.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+var jsp = require("./parse-js"),
+ pro = require("./process"),
+ slice = jsp.slice,
+ member = jsp.member,
+ curry = jsp.curry,
+ MAP = pro.MAP,
+ PRECEDENCE = jsp.PRECEDENCE,
+ OPERATORS = jsp.OPERATORS;
+
+function ast_squeeze_more(ast) {
+ var w = pro.ast_walker(), walk = w.walk, scope;
+ function with_scope(s, cont) {
+ var save = scope, ret;
+ scope = s;
+ ret = cont();
+ scope = save;
+ return ret;
+ };
+ function _lambda(name, args, body) {
+ return [ this[0], name, args, with_scope(body.scope, curry(MAP, body, walk)) ];
+ };
+ return w.with_walkers({
+ "toplevel": function(body) {
+ return [ this[0], with_scope(this.scope, curry(MAP, body, walk)) ];
+ },
+ "function": _lambda,
+ "defun": _lambda,
+ "new": function(ctor, args) {
+ if (ctor[0] == "name") {
+ if (ctor[1] == "Array" && !scope.has("Array")) {
+ if (args.length != 1) {
+ return [ "array", args ];
+ } else {
+ return walk([ "call", [ "name", "Array" ], args ]);
+ }
+ } else if (ctor[1] == "Object" && !scope.has("Object")) {
+ if (!args.length) {
+ return [ "object", [] ];
+ } else {
+ return walk([ "call", [ "name", "Object" ], args ]);
+ }
+ } else if ((ctor[1] == "RegExp" || ctor[1] == "Function" || ctor[1] == "Error") && !scope.has(ctor[1])) {
+ return walk([ "call", [ "name", ctor[1] ], args]);
+ }
+ }
+ },
+ "call": function(expr, args) {
+ if (expr[0] == "dot" && expr[1][0] == "string" && args.length == 1
+ && (args[0][1] > 0 && expr[2] == "substring" || expr[2] == "substr")) {
+ return [ "call", [ "dot", expr[1], "slice"], args];
+ }
+ if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) {
+ // foo.toString() ==> foo+""
+ if (expr[1][0] == "string") return expr[1];
+ return [ "binary", "+", expr[1], [ "string", "" ]];
+ }
+ if (expr[0] == "name") {
+ if (expr[1] == "Array" && args.length != 1 && !scope.has("Array")) {
+ return [ "array", args ];
+ }
+ if (expr[1] == "Object" && !args.length && !scope.has("Object")) {
+ return [ "object", [] ];
+ }
+ if (expr[1] == "String" && !scope.has("String")) {
+ return [ "binary", "+", args[0], [ "string", "" ]];
+ }
+ }
+ }
+ }, function() {
+ return walk(pro.ast_add_scope(ast));
+ });
+};
+
+exports.ast_squeeze_more = ast_squeeze_more;
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjspackagejson"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/package.json (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/package.json (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/package.json 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+{
+ "name": "uglify-js",
+ "description": "JavaScript parser and compressor/beautifier toolkit",
+ "author": {
+ "name": "Mihai Bazon",
+ "email": "mihai.bazon@gmail.com",
+ "url": "http://mihai.bazon.net/blog"
+ },
+ "version": "1.3.2",
+ "main": "./uglify-js.js",
+ "bin": {
+ "uglifyjs": "./bin/uglifyjs"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git@github.com:mishoo/UglifyJS.git"
+ },
+ "devDependencies": {
+ "nodeunit": "0.7.x"
+ },
+ "scripts": {
+ "test": "$(which nodeunit || echo node_modules/nodeunit/bin/nodeunit) test/unit/scripts.js && test/testparser.js && test/testconsolidator.js"
+ },
+ "readme": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"\nlang=\"en\" xml:lang=\"en\">\n<head>\n<title>UglifyJS – a JavaScript parser/compressor/beautifier</title>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\n<meta name=\"generator\" content=\"Org-mode\"/>\n<meta name=\"generated\" content=\"2011-12-09 14:59:08 EET\"/>\n<meta name=\"author\" content=\"Mihai Bazon\"/>\n<meta name=\"description\" content=\"a JavaScript parser/compressor/beautifier in JavaScript\"/>\n<meta name=\"keywords\" content=\"javascript
, js, parser, compiler, compressor, mangle, minify, minifier\"/>\n<style type=\"text/css\">\n <!--/*--><![CDATA[/*><!--*/\n html { font-family: Times, serif; font-size: 12pt; }\n .title { text-align: center; }\n .todo { color: red; }\n .done { color: green; }\n .tag { background-color: #add8e6; font-weight:normal }\n .target { }\n .timestamp { color: #bebebe; }\n .timestamp-kwd { color: #5f9ea0; }\n .right {margin-left:auto; margin-right:0px; text-align:right;}\n .left {margin-left:0px; margin-right:auto; text-align:left;}\n .center {margin-left:auto; margin-right:auto; text-align:center;}\n p.verse { margin-left: 3% }\n pre {\n\tborder: 1pt solid #AEBDCC;\n\tbackground-color: #F3F5F7;\n\tpadding: 5pt;\n\tfont-family: courier, monospace;\n font-size: 90%;\n overflow:auto;\n }\n table { border-collapse: collapse; }\n td, th { vertical-align: top; }\n th.right { text-align:center; }\n th.left { te
xt-align:center; }\n th.center { text-align:center; }\n td.right { text-align:right; }\n td.left { text-align:left; }\n td.center { text-align:center; }\n dt { font-weight: bold; }\n div.figure { padding: 0.5em; }\n div.figure p { text-align: center; }\n div.inlinetask {\n padding:10px;\n border:2px solid gray;\n margin:10px;\n background: #ffffcc;\n }\n textarea { overflow-x: auto; }\n .linenr { font-size:smaller }\n .code-highlighted {background-color:#ffff00;}\n .org-info-js_info-navigation { border-style:none; }\n #org-info-js_console-label { font-size:10px; font-weight:bold;\n white-space:nowrap; }\n .org-info-js_search-highlight {background-color:#ffff00; color:#000000;\n font-weight:bold; }\n /*]]>*/-->\n</style>\n<link rel=\"stylesheet\" type=\"text/css\" href=\"docstyle.css\" />\n<script type=\"text/javascript\">\n
<!--/*--><![CDATA[/*><!--*/\n function CodeHighlightOn(elem, id)\n {\n var target = document.getElementById(id);\n if(null != target) {\n elem.cacheClassElem = elem.className;\n elem.cacheClassTarget = target.className;\n target.className = \"code-highlighted\";\n elem.className = \"code-highlighted\";\n }\n }\n function CodeHighlightOff(elem, id)\n {\n var target = document.getElementById(id);\n if(elem.cacheClassElem)\n elem.className = elem.cacheClassElem;\n if(elem.cacheClassTarget)\n target.className = elem.cacheClassTarget;\n }\n/*]]>*///-->\n</script>\n\n</head>\n<body>\n\n<div id=\"preamble\">\n\n</div>\n\n<div id=\"content\">\n<h1 class=\"title\">UglifyJS – a JavaScript parser/compressor/beautifier</h1>\n\n\n<div id=\"table-of-contents\">\n<h2>Table of Contents</h2>\n<div id=\&qu
ot;text-table-of-contents\">\n<ul>\n<li><a href=\"#sec-1\">1 UglifyJS — a JavaScript parser/compressor/beautifier </a>\n<ul>\n<li><a href=\"#sec-1-1\">1.1 Unsafe transformations </a>\n<ul>\n<li><a href=\"#sec-1-1-1\">1.1.1 Calls involving the global Array constructor </a></li>\n<li><a href=\"#sec-1-1-2\">1.1.2 <code>obj.toString()</code> ==> <code>obj+“”</code> </a></li>\n</ul>\n</li>\n<li><a href=\"#sec-1-2\">1.2 Install (NPM) </a></li>\n<li><a href=\"#sec-1-3\">1.3 Install latest code from GitHub </a></li>\n<li><a href=\"#sec-1-4\">1.4 Usage </a>\n<ul>\n<li><a href=\"#sec-1-4-1\">1.4.1 API </a></li>\n<li><a href=\"#sec-1-4-2\"
;>1.4.2 Beautifier shortcoming – no more comments </a></li>\n<li><a href=\"#sec-1-4-3\">1.4.3 Use as a code pre-processor </a></li>\n</ul>\n</li>\n<li><a href=\"#sec-1-5\">1.5 Compression – how good is it? </a></li>\n<li><a href=\"#sec-1-6\">1.6 Bugs? </a></li>\n<li><a href=\"#sec-1-7\">1.7 Links </a></li>\n<li><a href=\"#sec-1-8\">1.8 License </a></li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n\n<div id=\"outline-container-1\" class=\"outline-2\">\n<h2 id=\"sec-1\"><span class=\"section-number-2\">1</span> UglifyJS — a JavaScript parser/compressor/beautifier </h2>\n<div class=\"outline-text-2\" id=\"text-1\">\n\n\n<p>\nThis package i
mplements a general-purpose JavaScript\nparser/compressor/beautifier toolkit. It is developed on <a href=\"http://nodejs.org/\">NodeJS</a>, but it\nshould work on any JavaScript platform supporting the CommonJS module system\n(and if your platform of choice doesn't support CommonJS, you can easily\nimplement it, or discard the <code>exports.*</code> lines from UglifyJS sources).\n</p>\n<p>\nThe tokenizer/parser generates an abstract syntax tree from JS code. You\ncan then traverse the AST to learn more about the code, or do various\nmanipulations on it. This part is implemented in <a href=\"../lib/parse-js.js\">parse-js.js</a> and it's a\nport to JavaScript of the excellent <a href=\"http://marijn.haverbeke.nl/parse-js/\">parse-js</a> Common Lisp library from <a href=\"http://marijn.haverbeke.nl/\">Marijn Haverbeke</a>.\n</p>\n<p>\n( See <a href=\"ht
tp://github.com/mishoo/cl-uglify-js\">cl-uglify-js</a> if you're looking for the Common Lisp version of\nUglifyJS. )\n</p>\n<p>\nThe second part of this package, implemented in <a href=\"../lib/process.js\">process.js</a>, inspects and\nmanipulates the AST generated by the parser to provide the following:\n</p>\n<ul>\n<li>ability to re-generate JavaScript code from the AST. Optionally\n indented—you can use this if you want to “beautify” a program that has\n been compressed, so that you can inspect the source. But you can also run\n our code generator to print out an AST without any whitespace, so you\n achieve compression as well.\n\n</li>\n<li>shorten variable names (usually to single characters). Our mangler will\n analyze the code and generate proper variable names, depending on scope\n and usage, and is smart enough to deal with globals defined elsewhere, or\n with <code>
eval()</code> calls or <code>with{}</code> statements. In short, if <code>eval()</code> or\n <code>with{}</code> are used in some scope, then all variables in that scope and any\n variables in the parent scopes will remain unmangled, and any references\n to such variables remain unmangled as well.\n\n</li>\n<li>various small optimizations that may lead to faster code but certainly\n lead to smaller code. Where possible, we do the following:\n\n<ul>\n<li>foo[\"bar\"] ==> foo.bar\n\n</li>\n<li>remove block brackets <code>{}</code>\n\n</li>\n<li>join consecutive var declarations:\n var a = 10; var b = 20; ==> var a=10,b=20;\n\n</li>\n<li>resolve simple constant expressions: 1 +2 * 3 ==> 7. We only do the\n replacement if the result occupies less bytes; for example 1/3 would\n translate to 0.333333333333, so in this case we do
n't replace it.\n\n</li>\n<li>consecutive statements in blocks are merged into a sequence; in many\n cases, this leaves blocks with a single statement, so then we can remove\n the block brackets.\n\n</li>\n<li>various optimizations for IF statements:\n\n<ul>\n<li>if (foo) bar(); else baz(); ==> foo?bar():baz();\n</li>\n<li>if (!foo) bar(); else baz(); ==> foo?baz():bar();\n</li>\n<li>if (foo) bar(); ==> foo&&bar();\n</li>\n<li>if (!foo) bar(); ==> foo||bar();\n</li>\n<li>if (foo) return bar(); else return baz(); ==> return foo?bar():baz();\n</li>\n<li>if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}\n\n</li>\n</ul>\n\n</li>\n<li>remove some unreachable code and warn about it (code that follows a\n <code>return</code>, <code>throw</code>, <code
>break</code> or <code>continue</code> statement, except\n function/variable declarations).\n\n</li>\n<li>act a limited version of a pre-processor (c.f. the pre-processor of\n C/C++) to allow you to safely replace selected global symbols with\n specified values. When combined with the optimisations above this can\n make UglifyJS operate slightly more like a compilation process, in\n that when certain symbols are replaced by constant values, entire code\n blocks may be optimised away as unreachable.\n</li>\n</ul>\n\n</li>\n</ul>\n\n\n\n</div>\n\n<div id=\"outline-container-1-1\" class=\"outline-3\">\n<h3 id=\"sec-1-1\"><span class=\"section-number-3\">1.1</span> <span class=\"target\">Unsafe transformations</span> </h3>\n<div class=\"outline-text-3\" id=\"text-1-1\">\n\n\n<p>\nThe
following transformations can in theory break code, although they're\nprobably safe in most practical cases. To enable them you need to pass the\n<code>--unsafe</code> flag.\n</p>\n\n</div>\n\n<div id=\"outline-container-1-1-1\" class=\"outline-4\">\n<h4 id=\"sec-1-1-1\"><span class=\"section-number-4\">1.1.1</span> Calls involving the global Array constructor </h4>\n<div class=\"outline-text-4\" id=\"text-1-1-1\">\n\n\n<p>\nThe following transformations occur:\n</p>\n\n\n\n<pre class=\"src src-js\"><span class=\"org-keyword\">new</span> <span class=\"org-type\">Array</span>(1, 2, 3, 4) => [1,2,3,4]\nArray(a, b, c) => [a,b,c]\n<span class=\"org-keyword\">new</span> <span class=\"org-type\">Array</span>(5) => A
rray(5)\n<span class=\"org-keyword\">new</span> <span class=\"org-type\">Array</span>(a) => Array(a)\n</pre>\n\n\n<p>\nThese are all safe if the Array name isn't redefined. JavaScript does allow\none to globally redefine Array (and pretty much everything, in fact) but I\npersonally don't see why would anyone do that.\n</p>\n<p>\nUglifyJS does handle the case where Array is redefined locally, or even\nglobally but with a <code>function</code> or <code>var</code> declaration. Therefore, in the\nfollowing cases UglifyJS <b>doesn't touch</b> calls or instantiations of Array:\n</p>\n\n\n\n<pre class=\"src src-js\"><span class=\"org-comment-delimiter\">// </span><span class=\"org-comment\">case 1. globally declared variable</span>\n <span class=\"org-keyword\">var</span> <span
class=\"org-variable-name\">Array</span>;\n <span class=\"org-keyword\">new</span> <span class=\"org-type\">Array</span>(1, 2, 3);\n Array(a, b);\n\n <span class=\"org-comment-delimiter\">// </span><span class=\"org-comment\">or (can be declared later)</span>\n <span class=\"org-keyword\">new</span> <span class=\"org-type\">Array</span>(1, 2, 3);\n <span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">Array</span>;\n\n <span class=\"org-comment-delimiter\">// </span><span class=\"org-comment\">or (can be a function)</span>\n <span class=\"org-keyword\">new</span> <span class=\"org-type\">Array</span>(1, 2, 3);\n <span class=\"org-keyword\">function</span>
<span class=\"org-function-name\">Array</span>() { ... }\n\n<span class=\"org-comment-delimiter\">// </span><span class=\"org-comment\">case 2. declared in a function</span>\n (<span class=\"org-keyword\">function</span>(){\n a = <span class=\"org-keyword\">new</span> <span class=\"org-type\">Array</span>(1, 2, 3);\n b = Array(5, 6);\n <span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">Array</span>;\n })();\n\n <span class=\"org-comment-delimiter\">// </span><span class=\"org-comment\">or</span>\n (<span class=\"org-keyword\">function</span>(<span class=\"org-variable-name\">Array</span>){\n <span class=\"org-keyword\">return</span> Array(5, 6, 7);\n })();\n\n &
lt;span class=\"org-comment-delimiter\">// </span><span class=\"org-comment\">or</span>\n (<span class=\"org-keyword\">function</span>(){\n <span class=\"org-keyword\">return</span> <span class=\"org-keyword\">new</span> <span class=\"org-type\">Array</span>(1, 2, 3, 4);\n <span class=\"org-keyword\">function</span> <span class=\"org-function-name\">Array</span>() { ... }\n })();\n\n <span class=\"org-comment-delimiter\">// </span><span class=\"org-comment\">etc.</span>\n</pre>\n\n\n</div>\n\n</div>\n\n<div id=\"outline-container-1-1-2\" class=\"outline-4\">\n<h4 id=\"sec-1-1-2\"><span class=\"section-number-4\">1.1.2</span> <code>obj.toString()</code> ==> <c
ode>obj+“”</code> </h4>\n<div class=\"outline-text-4\" id=\"text-1-1-2\">\n\n\n</div>\n</div>\n\n</div>\n\n<div id=\"outline-container-1-2\" class=\"outline-3\">\n<h3 id=\"sec-1-2\"><span class=\"section-number-3\">1.2</span> Install (NPM) </h3>\n<div class=\"outline-text-3\" id=\"text-1-2\">\n\n\n<p>\nUglifyJS is now available through NPM — <code>npm install uglify-js</code> should do\nthe job.\n</p>\n</div>\n\n</div>\n\n<div id=\"outline-container-1-3\" class=\"outline-3\">\n<h3 id=\"sec-1-3\"><span class=\"section-number-3\">1.3</span> Install latest code from GitHub </h3>\n<div class=\"outline-text-3\" id=\"text-1-3\">\n\n\n\n\n\n<pre class=\"src src-sh\"><span cla
ss=\"org-comment-delimiter\">## </span><span class=\"org-comment\">clone the repository</span>\nmkdir -p /where/you/wanna/put/it\n<span class=\"org-builtin\">cd</span> /where/you/wanna/put/it\ngit clone git://github.com/mishoo/UglifyJS.git\n\n<span class=\"org-comment-delimiter\">## </span><span class=\"org-comment\">make the module available to Node</span>\nmkdir -p ~/.node_libraries/\n<span class=\"org-builtin\">cd</span> ~/.node_libraries/\nln -s /where/you/wanna/put/it/UglifyJS/uglify-js.js\n\n<span class=\"org-comment-delimiter\">## </span><span class=\"org-comment\">and if you want the CLI script too:</span>\nmkdir -p ~/bin\n<span class=\"org-builtin\">cd</span> ~/bin\nln -s /where/you/wanna/put/it/UglifyJS/bin/uglifyjs\n <span class=\"org-comment-delimiter\"># </sp
an><span class=\"org-comment\">(then add ~/bin to your $PATH if it's not there already)</span>\n</pre>\n\n\n</div>\n\n</div>\n\n<div id=\"outline-container-1-4\" class=\"outline-3\">\n<h3 id=\"sec-1-4\"><span class=\"section-number-3\">1.4</span> Usage </h3>\n<div class=\"outline-text-3\" id=\"text-1-4\">\n\n\n<p>\nThere is a command-line tool that exposes the functionality of this library\nfor your shell-scripting needs:\n</p>\n\n\n\n<pre class=\"src src-sh\">uglifyjs [ options... ] [ filename ]\n</pre>\n\n\n<p>\n<code>filename</code> should be the last argument and should name the file from which\nto read the JavaScript code. If you don't specify it, it will read code\nfrom STDIN.\n</p>\n<p>\nSupported options:\n</p>\n<ul>\n<li><code>-b</code> or <
code>--beautify</code> — output indented code; when passed, additional\n options control the beautifier:\n\n<ul>\n<li><code>-i N</code> or <code>--indent N</code> — indentation level (number of spaces)\n\n</li>\n<li><code>-q</code> or <code>--quote-keys</code> — quote keys in literal objects (by default,\n only keys that cannot be identifier names will be quotes).\n\n</li>\n</ul>\n\n</li>\n<li><code>--ascii</code> — pass this argument to encode non-ASCII characters as\n <code>\\uXXXX</code> sequences. By default UglifyJS won't bother to do it and will\n output Unicode characters instead. (the output is always encoded in UTF8,\n but if you pass this option you'll only get ASCII).\n\n</li>\n<li><code>-nm</code> or <code>--no-mangle</code> — don't mangle names.\n\n&
lt;/li>\n<li><code>-nmf</code> or <code>--no-mangle-functions</code> – in case you want to mangle variable\n names, but not touch function names.\n\n</li>\n<li><code>-ns</code> or <code>--no-squeeze</code> — don't call <code>ast_squeeze()</code> (which does various\n optimizations that result in smaller, less readable code).\n\n</li>\n<li><code>-mt</code> or <code>--mangle-toplevel</code> — mangle names in the toplevel scope too\n (by default we don't do this).\n\n</li>\n<li><code>--no-seqs</code> — when <code>ast_squeeze()</code> is called (thus, unless you pass\n <code>--no-squeeze</code>) it will reduce consecutive statements in blocks into a\n sequence. For example, \"a = 10; b = 20; foo();\" will be written as\n \"a=10,b=20,foo();\". In various occa
sions, this allows us to discard the\n block brackets (since the block becomes a single statement). This is ON\n by default because it seems safe and saves a few hundred bytes on some\n libs that I tested it on, but pass <code>--no-seqs</code> to disable it.\n\n</li>\n<li><code>--no-dead-code</code> — by default, UglifyJS will remove code that is\n obviously unreachable (code that follows a <code>return</code>, <code>throw</code>, <code>break</code> or\n <code>continue</code> statement and is not a function/variable declaration). Pass\n this option to disable this optimization.\n\n</li>\n<li><code>-nc</code> or <code>--no-copyright</code> — by default, <code>uglifyjs</code> will keep the initial\n comment tokens in the generated code (assumed to be copyright information\n etc.). If you pass this it will discard it.\n\n<
/li>\n<li><code>-o filename</code> or <code>--output filename</code> — put the result in <code>filename</code>. If\n this isn't given, the result goes to standard output (or see next one).\n\n</li>\n<li><code>--overwrite</code> — if the code is read from a file (not from STDIN) and you\n pass <code>--overwrite</code> then the output will be written in the same file.\n\n</li>\n<li><code>--ast</code> — pass this if you want to get the Abstract Syntax Tree instead\n of JavaScript as output. Useful for debugging or learning more about the\n internals.\n\n</li>\n<li><code>-v</code> or <code>--verbose</code> — output some notes on STDERR (for now just how long\n each operation takes).\n\n</li>\n<li><code>-d SYMBOL[=VALUE]</code> or <code>--define SYMBOL[=VALUE]</code>
— will replace\n all instances of the specified symbol where used as an identifier\n (except where symbol has properly declared by a var declaration or\n use as function parameter or similar) with the specified value. This\n argument may be specified multiple times to define multiple\n symbols - if no value is specified the symbol will be replaced with\n the value <code>true</code>, or you can specify a numeric value (such as\n <code>1024</code>), a quoted string value (such as =\"object\"= or\n ='https://github.com'<code>), or the name of another symbol or keyword (such as =null</code> or <code>document</code>).\n This allows you, for example, to assign meaningful names to key\n constant values but discard the symbolic names in the uglified\n version for brevity/efficiency, or when used wth care, allows\n UglifyJS to operate as a form of <b>conditional compilation</b>\n whereby defining a
ppropriate values may, by dint of the constant\n folding and dead code removal features above, remove entire\n superfluous code blocks (e.g. completely remove instrumentation or\n trace code for production use).\n Where string values are being defined, the handling of quotes are\n likely to be subject to the specifics of your command shell\n environment, so you may need to experiment with quoting styles\n depending on your platform, or you may find the option\n <code>--define-from-module</code> more suitable for use.\n\n</li>\n<li><code>-define-from-module SOMEMODULE</code> — will load the named module (as\n per the NodeJS <code>require()</code> function) and iterate all the exported\n properties of the module defining them as symbol names to be defined\n (as if by the <code>--define</code> option) per the name of each property\n (i.e. without the module name prefix) and given the value of the\n prope
rty. This is a much easier way to handle and document groups of\n symbols to be defined rather than a large number of <code>--define</code>\n options.\n\n</li>\n<li><code>--unsafe</code> — enable other additional optimizations that are known to be\n unsafe in some contrived situations, but could still be generally useful.\n For now only these:\n\n<ul>\n<li>foo.toString() ==> foo+\"\"\n</li>\n<li>new Array(x,…) ==> [x,…]\n</li>\n<li>new Array(x) ==> Array(x)\n\n</li>\n</ul>\n\n</li>\n<li><code>--max-line-len</code> (default 32K characters) — add a newline after around\n 32K characters. I've seen both FF and Chrome croak when all the code was\n on a single line of around 670K. Pass –max-line-len 0 to disable this\n safety feature.\n\n</li>\n<li><code>--reserved-names&
lt;/code> — some libraries rely on certain names to be used, as\n pointed out in issue #92 and #81, so this option allow you to exclude such\n names from the mangler. For example, to keep names <code>require</code> and <code>$super</code>\n intact you'd specify –reserved-names \"require,$super\".\n\n</li>\n<li><code>--inline-script</code> – when you want to include the output literally in an\n HTML <code><script></code> tag you can use this option to prevent <code></script</code> from\n showing up in the output.\n\n</li>\n<li><code>--lift-vars</code> – when you pass this, UglifyJS will apply the following\n transformations (see the notes in API, <code>ast_lift_variables</code>):\n\n<ul>\n<li>put all <code>var</code> declarations at the start of the scope\n</li>\n<l
i>make sure a variable is declared only once\n</li>\n<li>discard unused function arguments\n</li>\n<li>discard unused inner (named) functions\n</li>\n<li>finally, try to merge assignments into that one <code>var</code> declaration, if\n possible.\n</li>\n</ul>\n\n</li>\n</ul>\n\n\n\n</div>\n\n<div id=\"outline-container-1-4-1\" class=\"outline-4\">\n<h4 id=\"sec-1-4-1\"><span class=\"section-number-4\">1.4.1</span> API </h4>\n<div class=\"outline-text-4\" id=\"text-1-4-1\">\n\n\n<p>\nTo use the library from JavaScript, you'd do the following (example for\nNodeJS):\n</p>\n\n\n\n<pre class=\"src src-js\"><span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">jsp</span> = require(<span class=\"org-string\"&g
t;\"uglify-js\"</span>).parser;\n<span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">pro</span> = require(<span class=\"org-string\">\"uglify-js\"</span>).uglify;\n\n<span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">orig_code</span> = <span class=\"org-string\">\"... JS code here\"</span>;\n<span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">ast</span> = jsp.parse(orig_code); <span class=\"org-comment-delimiter\">// </span><span class=\"org-comment\">parse code and get the initial AST</span>\nast = pro.ast_mangle(ast); <span class=\"org-comment-delimiter\">// </span><span class=\"org-comment\">get a new AST with mangled names</
span>\nast = pro.ast_squeeze(ast); <span class=\"org-comment-delimiter\">// </span><span class=\"org-comment\">get an AST with compression optimizations</span>\n<span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">final_code</span> = pro.gen_code(ast); <span class=\"org-comment-delimiter\">// </span><span class=\"org-comment\">compressed code here</span>\n</pre>\n\n\n<p>\nThe above performs the full compression that is possible right now. As you\ncan see, there are a sequence of steps which you can apply. For example if\nyou want compressed output but for some reason you don't want to mangle\nvariable names, you would simply skip the line that calls\n<code>pro.ast_mangle(ast)</code>.\n</p>\n<p>\nSome of these functions take optional arguments. Here's a description:\n</p>\n<ul>\n&l
t;li><code>jsp.parse(code, strict_semicolons)</code> – parses JS code and returns an AST.\n <code>strict_semicolons</code> is optional and defaults to <code>false</code>. If you pass\n <code>true</code> then the parser will throw an error when it expects a semicolon and\n it doesn't find it. For most JS code you don't want that, but it's useful\n if you want to strictly sanitize your code.\n\n</li>\n<li><code>pro.ast_lift_variables(ast)</code> – merge and move <code>var</code> declarations to the\n scop of the scope; discard unused function arguments or variables; discard\n unused (named) inner functions. It also tries to merge assignments\n following the <code>var</code> declaration into it.\n\n<p>\n If your code is very hand-optimized concerning <code>var</code> declarations, this\n lifting variable declarations might actually increas
e size. For me it\n helps out. On jQuery it adds 865 bytes (243 after gzip). YMMV. Also\n note that (since it's not enabled by default) this operation isn't yet\n heavily tested (please report if you find issues!).\n</p>\n<p>\n Note that although it might increase the image size (on jQuery it gains\n 865 bytes, 243 after gzip) it's technically more correct: in certain\n situations, dead code removal might drop variable declarations, which\n would not happen if the variables are lifted in advance.\n</p>\n<p>\n Here's an example of what it does:\n</p></li>\n</ul>\n\n\n\n\n\n<pre class=\"src src-js\"><span class=\"org-keyword\">function</span> <span class=\"org-function-name\">f</span>(<span class=\"org-variable-name\">a</span>, <span class=\"org-variable-name\">b</span>, <span class=\"org-variable-name\">c</spa
n>, <span class=\"org-variable-name\">d</span>, <span class=\"org-variable-name\">e</span>) {\n <span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">q</span>;\n <span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">w</span>;\n w = 10;\n q = 20;\n <span class=\"org-keyword\">for</span> (<span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">i</span> = 1; i < 10; ++i) {\n <span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">boo</span> = foo(a);\n }\n <span class=\"org-keyword\">for</span> (<span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">i</span>
= 0; i < 1; ++i) {\n <span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">boo</span> = bar(c);\n }\n <span class=\"org-keyword\">function</span> <span class=\"org-function-name\">foo</span>(){ ... }\n <span class=\"org-keyword\">function</span> <span class=\"org-function-name\">bar</span>(){ ... }\n <span class=\"org-keyword\">function</span> <span class=\"org-function-name\">baz</span>(){ ... }\n}\n\n<span class=\"org-comment-delimiter\">// </span><span class=\"org-comment\">transforms into ==></span>\n\n<span class=\"org-keyword\">function</span> <span class=\"org-function-name\">f</span>(<span class=\"org-variable-name\">a</span>, <span class=
\"org-variable-name\">b</span>, <span class=\"org-variable-name\">c</span>) {\n <span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">i</span>, <span class=\"org-variable-name\">boo</span>, <span class=\"org-variable-name\">w</span> = 10, <span class=\"org-variable-name\">q</span> = 20;\n <span class=\"org-keyword\">for</span> (i = 1; i < 10; ++i) {\n boo = foo(a);\n }\n <span class=\"org-keyword\">for</span> (i = 0; i < 1; ++i) {\n boo = bar(c);\n }\n <span class=\"org-keyword\">function</span> <span class=\"org-function-name\">foo</span>() { ... }\n <span class=\"org-keyword\">function</span> <span class=\"org-function-name\">bar</span>
() { ... }\n}\n</pre>\n\n\n<ul>\n<li><code>pro.ast_mangle(ast, options)</code> – generates a new AST containing mangled\n (compressed) variable and function names. It supports the following\n options:\n\n<ul>\n<li><code>toplevel</code> – mangle toplevel names (by default we don't touch them).\n</li>\n<li><code>except</code> – an array of names to exclude from compression.\n</li>\n<li><code>defines</code> – an object with properties named after symbols to\n replace (see the <code>--define</code> option for the script) and the values\n representing the AST replacement value.\n\n</li>\n</ul>\n\n</li>\n<li><code>pro.ast_squeeze(ast, options)</code> – employs further optimizations designed\n to reduce the size of the code that <code>gen_code</code> would generate from t
he\n AST. Returns a new AST. <code>options</code> can be a hash; the supported options\n are:\n\n<ul>\n<li><code>make_seqs</code> (default true) which will cause consecutive statements in a\n block to be merged using the \"sequence\" (comma) operator\n\n</li>\n<li><code>dead_code</code> (default true) which will remove unreachable code.\n\n</li>\n</ul>\n\n</li>\n<li><code>pro.gen_code(ast, options)</code> – generates JS code from the AST. By\n default it's minified, but using the <code>options</code> argument you can get nicely\n formatted output. <code>options</code> is, well, optional :-) and if you pass it it\n must be an object and supports the following properties (below you can see\n the default values):\n\n<ul>\n<li><code>beautify: false</code> – pass <code>true</code> if you want
indented output\n</li>\n<li><code>indent_start: 0</code> (only applies when <code>beautify</code> is <code>true</code>) – initial\n indentation in spaces\n</li>\n<li><code>indent_level: 4</code> (only applies when <code>beautify</code> is <code>true</code>) --\n indentation level, in spaces (pass an even number)\n</li>\n<li><code>quote_keys: false</code> – if you pass <code>true</code> it will quote all keys in\n literal objects\n</li>\n<li><code>space_colon: false</code> (only applies when <code>beautify</code> is <code>true</code>) – wether\n to put a space before the colon in object literals\n</li>\n<li><code>ascii_only: false</code> – pass <code>true</code> if you want to encode non-ASCII\n characters as <cod
e>\\uXXXX</code>.\n</li>\n<li><code>inline_script: false</code> – pass <code>true</code> to escape occurrences of\n <code></script</code> in strings\n</li>\n</ul>\n\n</li>\n</ul>\n\n\n</div>\n\n</div>\n\n<div id=\"outline-container-1-4-2\" class=\"outline-4\">\n<h4 id=\"sec-1-4-2\"><span class=\"section-number-4\">1.4.2</span> Beautifier shortcoming – no more comments </h4>\n<div class=\"outline-text-4\" id=\"text-1-4-2\">\n\n\n<p>\nThe beautifier can be used as a general purpose indentation tool. It's\nuseful when you want to make a minified file readable. One limitation,\nthough, is that it discards all comments, so you don't really want to use it\nto reformat your code, unless you don't have, or don't care about, comments.\n</p>\n<p>\nIn fact it
's not the beautifier who discards comments — they are dumped at\nthe parsing stage, when we build the initial AST. Comments don't really\nmake sense in the AST, and while we could add nodes for them, it would be\ninconvenient because we'd have to add special rules to ignore them at all\nthe processing stages.\n</p>\n</div>\n\n</div>\n\n<div id=\"outline-container-1-4-3\" class=\"outline-4\">\n<h4 id=\"sec-1-4-3\"><span class=\"section-number-4\">1.4.3</span> Use as a code pre-processor </h4>\n<div class=\"outline-text-4\" id=\"text-1-4-3\">\n\n\n<p>\nThe <code>--define</code> option can be used, particularly when combined with the\nconstant folding logic, as a form of pre-processor to enable or remove\nparticular constructions, such as might be used for instrumenting\ndevelopment code, or to produce variations aimed at a specific\nplatform.\
n</p>\n<p>\nThe code below illustrates the way this can be done, and how the\nsymbol replacement is performed.\n</p>\n\n\n\n<pre class=\"src src-js\">CLAUSE1: <span class=\"org-keyword\">if</span> (<span class=\"org-keyword\">typeof</span> DEVMODE === <span class=\"org-string\">'undefined'</span>) {\n DEVMODE = <span class=\"org-constant\">true</span>;\n}\n\n<span class=\"org-function-name\">CLAUSE2</span>: <span class=\"org-keyword\">function</span> init() {\n <span class=\"org-keyword\">if</span> (DEVMODE) {\n console.log(<span class=\"org-string\">\"init() called\"</span>);\n }\n ....\n DEVMODE &amp;&amp; console.log(<span class=\"org-string\">\"init() complete\"</span>);\n}\n\n<span class=\&
quot;org-function-name\">CLAUSE3</span>: <span class=\"org-keyword\">function</span> reportDeviceStatus(<span class=\"org-variable-name\">device</span>) {\n <span class=\"org-keyword\">var</span> <span class=\"org-variable-name\">DEVMODE</span> = device.mode, <span class=\"org-variable-name\">DEVNAME</span> = device.name;\n <span class=\"org-keyword\">if</span> (DEVMODE === <span class=\"org-string\">'open'</span>) {\n ....\n }\n}\n</pre>\n\n\n<p>\nWhen the above code is normally executed, the undeclared global\nvariable <code>DEVMODE</code> will be assigned the value <b>true</b> (see <code>CLAUSE1</code>)\nand so the <code>init()</code> function (<code>CLAUSE2</code>) will write messages to the\nconsole log when executed, but in &
lt;code>CLAUSE3</code> a locally declared\nvariable will mask access to the <code>DEVMODE</code> global symbol.\n</p>\n<p>\nIf the above code is processed by UglifyJS with an argument of\n<code>--define DEVMODE=false</code> then UglifyJS will replace <code>DEVMODE</code> with the\nboolean constant value <b>false</b> within <code>CLAUSE1</code> and <code>CLAUSE2</code>, but it\nwill leave <code>CLAUSE3</code> as it stands because there <code>DEVMODE</code> resolves to\na validly declared variable.\n</p>\n<p>\nAnd more so, the constant-folding features of UglifyJS will recognise\nthat the <code>if</code> condition of <code>CLAUSE1</code> is thus always false, and so will\nremove the test and body of <code>CLAUSE1</code> altogether (including the\notherwise slightly problematical statement <code>false = true;</code
> which it\nwill have formed by replacing <code>DEVMODE</code> in the body). Similarly,\nwithin <code>CLAUSE2</code> both calls to <code>console.log()</code> will be removed\naltogether.\n</p>\n<p>\nIn this way you can mimic, to a limited degree, the functionality of\nthe C/C++ pre-processor to enable or completely remove blocks\ndepending on how certain symbols are defined - perhaps using UglifyJS\nto generate different versions of source aimed at different\nenvironments\n</p>\n<p>\nIt is recommmended (but not made mandatory) that symbols designed for\nthis purpose are given names consisting of <code>UPPER_CASE_LETTERS</code> to\ndistinguish them from other (normal) symbols and avoid the sort of\nclash that <code>CLAUSE3</code> above illustrates.\n</p>\n</div>\n</div>\n\n</div>\n\n<div id=\"outline-container-1-5\" class=\"outline-3\">\n<h3 id=
\"sec-1-5\"><span class=\"section-number-3\">1.5</span> Compression – how good is it? </h3>\n<div class=\"outline-text-3\" id=\"text-1-5\">\n\n\n<p>\nHere are updated statistics. (I also updated my Google Closure and YUI\ninstallations).\n</p>\n<p>\nWe're still a lot better than YUI in terms of compression, though slightly\nslower. We're still a lot faster than Closure, and compression after gzip\nis comparable.\n</p>\n<table border=\"2\" cellspacing=\"0\" cellpadding=\"6\" rules=\"groups\" frame=\"hsides\">\n<caption></caption>\n<colgroup><col class=\"left\" /><col class=\"left\" /><col class=\"right\" /><col class=\"left\" /><col class=\"right\" /><col class=\"left\" /><col class=\"right\" />\n<
;/colgroup>\n<thead>\n<tr><th scope=\"col\" class=\"left\">File</th><th scope=\"col\" class=\"left\">UglifyJS</th><th scope=\"col\" class=\"right\">UglifyJS+gzip</th><th scope=\"col\" class=\"left\">Closure</th><th scope=\"col\" class=\"right\">Closure+gzip</th><th scope=\"col\" class=\"left\">YUI</th><th scope=\"col\" class=\"right\">YUI+gzip</th></tr>\n</thead>\n<tbody>\n<tr><td class=\"left\">jquery-1.6.2.js</td><td class=\"left\">91001 (0:01.59)</td><td class=\"right\">31896</td><td class=\"left\">90678 (0:07.40)</td><td class=\"right\">31979</td><td class=\"left\">101527 (0:01.82)</td><t
d class=\"right\">34646</td></tr>\n<tr><td class=\"left\">paper.js</td><td class=\"left\">142023 (0:01.65)</td><td class=\"right\">43334</td><td class=\"left\">134301 (0:07.42)</td><td class=\"right\">42495</td><td class=\"left\">173383 (0:01.58)</td><td class=\"right\">48785</td></tr>\n<tr><td class=\"left\">prototype.js</td><td class=\"left\">88544 (0:01.09)</td><td class=\"right\">26680</td><td class=\"left\">86955 (0:06.97)</td><td class=\"right\">26326</td><td class=\"left\">92130 (0:00.79)</td><td class=\"right\">28624</td></tr>\n<tr><td class=\"left\">thelib-full.js (DynarchLIB)</td><td class=\&
quot;left\">251939 (0:02.55)</td><td class=\"right\">72535</td><td class=\"left\">249911 (0:09.05)</td><td class=\"right\">72696</td><td class=\"left\">258869 (0:01.94)</td><td class=\"right\">76584</td></tr>\n</tbody>\n</table>\n\n\n</div>\n\n</div>\n\n<div id=\"outline-container-1-6\" class=\"outline-3\">\n<h3 id=\"sec-1-6\"><span class=\"section-number-3\">1.6</span> Bugs? </h3>\n<div class=\"outline-text-3\" id=\"text-1-6\">\n\n\n<p>\nUnfortunately, for the time being there is no automated test suite. But I\nran the compressor manually on non-trivial code, and then I tested that the\ngenerated code works as expected. A few hundred times.\n</p>\n<p>\nDynarchLIB was started in times when there was no good JS minifie
r.\nTherefore I was quite religious about trying to write short code manually,\nand as such DL contains a lot of syntactic hacks<sup><a class=\"footref\" name=\"fnr.1\" href=\"#fn.1\">1</a></sup> such as “foo == bar ? a\n= 10 : b = 20”, though the more readable version would clearly be to use\n“if/else”.\n</p>\n<p>\nSince the parser/compressor runs fine on DL and jQuery, I'm quite confident\nthat it's solid enough for production use. If you can identify any bugs,\nI'd love to hear about them (<a href=\"http://groups.google.com/group/uglifyjs\">use the Google Group</a> or email me directly).\n</p>\n</div>\n\n</div>\n\n<div id=\"outline-container-1-7\" class=\"outline-3\">\n<h3 id=\"sec-1-7\"><span class=\"section-number-3\">1.7</span> Links </h3>\n<div class=\"outline-text-3\" id=\"t
ext-1-7\">\n\n\n<ul>\n<li>Twitter: <a href=\"http://twitter.com/UglifyJS\">@UglifyJS</a>\n</li>\n<li>Project at GitHub: <a href=\"http://github.com/mishoo/UglifyJS\">http://github.com/mishoo/UglifyJS</a>\n</li>\n<li>Google Group: <a href=\"http://groups.google.com/group/uglifyjs\">http://groups.google.com/group/uglifyjs</a>\n</li>\n<li>Common Lisp JS parser: <a href=\"http://marijn.haverbeke.nl/parse-js/\">http://marijn.haverbeke.nl/parse-js/</a>\n</li>\n<li>JS-to-Lisp compiler: <a href=\"http://github.com/marijnh/js\">http://github.com/marijnh/js</a>\n</li>\n<li>Common Lisp JS uglifier: <a href=\"http://github.com/mishoo/cl-uglify-js\">http://github.com/mishoo/cl-uglify-js</a>\n</li>\n</ul>\n\n\n</div>\n\n</div>\n\n<div id=\"outline-container
-1-8\" class=\"outline-3\">\n<h3 id=\"sec-1-8\"><span class=\"section-number-3\">1.8</span> License </h3>\n<div class=\"outline-text-3\" id=\"text-1-8\">\n\n\n<p>\nUglifyJS is released under the BSD license:\n</p>\n\n\n\n<pre class=\"example\">Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>\nBased on parse-js (http://marijn.haverbeke.nl/parse-js/).\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n * Redistributions of source code must retain the above\n copyright notice, this list of conditions and the following\n disclaimer.\n\n * Redistributions in binary form must reproduce the above\n copyright notice, this list of conditions and the following\n disclaimer in the documentation and/or other materials\n provided wit
h the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\nOR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\nTORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\nTHE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGE.\n</pre>\n\n\n<div id=\"footnotes\">\n<h2 class=\"footnotes\">Footnotes: </h2>\n<div id=\"text-footnotes\">\n<p class=\"footnote\"><sup><a class=\"f
ootnum\" name=\"fn.1\" href=\"#fnr.1\">1</a></sup> I even reported a few bugs and suggested some fixes in the original\n <a href=\"http://marijn.haverbeke.nl/parse-js/\">parse-js</a> library, and Marijn pushed fixes literally in minutes.\n</p></div>\n</div>\n</div>\n\n</div>\n</div>\n</div>\n\n<div id=\"postamble\">\n<p class=\"date\">Date: 2011-12-09 14:59:08 EET</p>\n<p class=\"author\">Author: Mihai Bazon</p>\n<p class=\"creator\">Org version 7.7 with Emacs version 23</p>\n<a href=\"http://validator.w3.org/check?uri=referer\">Validate XHTML 1.0</a>\n\n</div>\n</body>\n</html>\n",
+ "_id": "uglify-js@1.3.2",
+ "dist": {
+ "shasum": "0f36c685d58468a2a35945eaaa5f32a3fda555d8"
+ },
+ "_from": "uglify-js@1.3.2"
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestbeautifyjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/beautify.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/beautify.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/beautify.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+#! /usr/bin/env node
+
+global.sys = require("sys");
+var fs = require("fs");
+
+var jsp = require("../lib/parse-js");
+var pro = require("../lib/process");
+
+var filename = process.argv[2];
+fs.readFile(filename, "utf8", function(err, text){
+ try {
+ var ast = time_it("parse", function(){ return jsp.parse(text); });
+ ast = time_it("mangle", function(){ return pro.ast_mangle(ast); });
+ ast = time_it("squeeze", function(){ return pro.ast_squeeze(ast); });
+ var gen = time_it("generate", function(){ return pro.gen_code(ast, false); });
+ sys.puts(gen);
+ } catch(ex) {
+ sys.debug(ex.stack);
+ sys.debug(sys.inspect(ex));
+ sys.debug(JSON.stringify(ex));
+ }
+});
+
+function time_it(name, cont) {
+ var t1 = new Date().getTime();
+ try { return cont(); }
+ finally { sys.debug("// " + name + ": " + ((new Date().getTime() - t1) / 1000).toFixed(3) + " sec."); }
+};
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/beautify.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstesttestparserjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/testparser.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/testparser.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/testparser.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,409 @@
</span><ins>+#! /usr/bin/env node
+global.DIGITS_OVERRIDE_FOR_TESTING = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
+
+var parseJS = require("../lib/parse-js");
+var sys = require("sys");
+
+// write debug in a very straightforward manner
+var debug = function(){
+ sys.log(Array.prototype.slice.call(arguments).join(', '));
+};
+
+var testsPassed = true;
+
+ParserTestSuite(function(i, input, desc){
+ try {
+ parseJS.parse(input);
+ debug("ok " + i + ": " + desc);
+ } catch(e){
+ debug("FAIL " + i + " " + desc + " (" + e + ")");
+ testsPassed = false;
+ }
+});
+
+process.exit(testsPassed ? 0 : 1);
+
+function ParserTestSuite(callback){
+ var inps = [
+ ["var abc;", "Regular variable statement w/o assignment"],
+ ["var abc = 5;", "Regular variable statement with assignment"],
+ ["/* */;", "Multiline comment"],
+ ['/** **/;', 'Double star multiline comment'],
+ ["var f = function(){;};", "Function expression in var assignment"],
+ ['hi; // moo\n;', 'single line comment'],
+ ['var varwithfunction;', 'Dont match keywords as substrings'], // difference between `var withsomevar` and `"str"` (local search and lits)
+ ['a + b;', 'addition'],
+ ["'a';", 'single string literal'],
+ ["'a\\n';", 'single string literal with escaped return'],
+ ['"a";', 'double string literal'],
+ ['"a\\n";', 'double string literal with escaped return'],
+ ['"var";', 'string is a keyword'],
+ ['"variable";', 'string starts with a keyword'],
+ ['"somevariable";', 'string contains a keyword'],
+ ['"somevar";', 'string ends with a keyword'],
+ ['500;', 'int literal'],
+ ['500.;', 'float literal w/o decimals'],
+ ['500.432;', 'float literal with decimals'],
+ ['.432432;', 'float literal w/o int'],
+ ['(a,b,c);', 'parens and comma'],
+ ['[1,2,abc];', 'array literal'],
+ ['var o = {a:1};', 'object literal unquoted key'],
+ ['var o = {"b":2};', 'object literal quoted key'], // opening curly may not be at the start of a statement...
+ ['var o = {c:c};', 'object literal keyname is identifier'],
+ ['var o = {a:1,"b":2,c:c};', 'object literal combinations'],
+ ['var x;\nvar y;', 'two lines'],
+ ['var x;\nfunction n(){; }', 'function def'],
+ ['var x;\nfunction n(abc){; }', 'function def with arg'],
+ ['var x;\nfunction n(abc, def){ ;}', 'function def with args'],
+ ['function n(){ "hello"; }', 'function def with body'],
+ ['/a/;', 'regex literal'],
+ ['/a/b;', 'regex literal with flag'],
+ ['/a/ / /b/;', 'regex div regex'],
+ ['a/b/c;', 'triple division looks like regex'],
+ ['+function(){/regex/;};', 'regex at start of function body'],
+ // http://code.google.com/p/es-lab/source/browse/trunk/tests/parser/parsertests.js?r=86
+ // http://code.google.com/p/es-lab/source/browse/trunk/tests/parser/parsertests.js?r=430
+
+ // first tests for the lexer, should also parse as program (when you append a semi)
+
+ // comments
+ ['//foo!@#^&$1234\nbar;', 'single line comment'],
+ ['/* abcd!@#@$* { } && null*/;', 'single line multi line comment'],
+ ['/*foo\nbar*/;','multi line comment'],
+ ['/*x*x*/;','multi line comment with *'],
+ ['/**/;','empty comment'],
+ // identifiers
+ ["x;",'1 identifier'],
+ ["_x;",'2 identifier'],
+ ["xyz;",'3 identifier'],
+ ["$x;",'4 identifier'],
+ ["x$;",'5 identifier'],
+ ["_;",'6 identifier'],
+ ["x5;",'7 identifier'],
+ ["x_y;",'8 identifier'],
+ ["x+5;",'9 identifier'],
+ ["xyz123;",'10 identifier'],
+ ["x1y1z1;",'11 identifier'],
+ ["foo\\u00D8bar;",'12 identifier unicode escape'],
+ //["foo�bar;",'13 identifier unicode embedded (might fail)'],
+ // numbers
+ ["5;", '1 number'],
+ ["5.5;", '2 number'],
+ ["0;", '3 number'],
+ ["0.0;", '4 number'],
+ ["0.001;", '5 number'],
+ ["1.e2;", '6 number'],
+ ["1.e-2;", '7 number'],
+ ["1.E2;", '8 number'],
+ ["1.E-2;", '9 number'],
+ [".5;", '10 number'],
+ [".5e3;", '11 number'],
+ [".5e-3;", '12 number'],
+ ["0.5e3;", '13 number'],
+ ["55;", '14 number'],
+ ["123;", '15 number'],
+ ["55.55;", '16 number'],
+ ["55.55e10;", '17 number'],
+ ["123.456;", '18 number'],
+ ["1+e;", '20 number'],
+ ["0x01;", '22 number'],
+ ["0XCAFE;", '23 number'],
+ ["0x12345678;", '24 number'],
+ ["0x1234ABCD;", '25 number'],
+ ["0x0001;", '26 number'],
+ // strings
+ ["\"foo\";", '1 string'],
+ ["\'foo\';", '2 string'],
+ ["\"x\";", '3 string'],
+ ["\'\';", '4 string'],
+ ["\"foo\\tbar\";", '5 string'],
+ ["\"!@#$%^&*()_+{}[]\";", '6 string'],
+ ["\"/*test*/\";", '7 string'],
+ ["\"//test\";", '8 string'],
+ ["\"\\\\\";", '9 string'],
+ ["\"\\u0001\";", '10 string'],
+ ["\"\\uFEFF\";", '11 string'],
+ ["\"\\u10002\";", '12 string'],
+ ["\"\\x55\";", '13 string'],
+ ["\"\\x55a\";", '14 string'],
+ ["\"a\\\\nb\";", '15 string'],
+ ['";"', '16 string: semi in a string'],
+ ['"a\\\nb";', '17 string: line terminator escape'],
+ // literals
+ ["null;", "null"],
+ ["true;", "true"],
+ ["false;", "false"],
+ // regex
+ ["/a/;", "1 regex"],
+ ["/abc/;", "2 regex"],
+ ["/abc[a-z]*def/g;", "3 regex"],
+ ["/\\b/;", "4 regex"],
+ ["/[a-zA-Z]/;", "5 regex"],
+
+ // program tests (for as far as they havent been covered above)
+
+ // regexp
+ ["/foo(.*)/g;", "another regexp"],
+ // arrays
+ ["[];", "1 array"],
+ ["[ ];", "2 array"],
+ ["[1];", "3 array"],
+ ["[1,2];", "4 array"],
+ ["[1,2,,];", "5 array"],
+ ["[1,2,3];", "6 array"],
+ ["[1,2,3,,,];", "7 array"],
+ // objects
+ ["{};", "1 object"],
+ ["({x:5});", "2 object"],
+ ["({x:5,y:6});", "3 object"],
+ ["({x:5,});", "4 object"],
+ ["({if:5});", "5 object"],
+ ["({ get x() {42;} });", "6 object"],
+ ["({ set y(a) {1;} });", "7 object"],
+ // member expression
+ ["o.m;", "1 member expression"],
+ ["o['m'];", "2 member expression"],
+ ["o['n']['m'];", "3 member expression"],
+ ["o.n.m;", "4 member expression"],
+ ["o.if;", "5 member expression"],
+ // call and invoke expressions
+ ["f();", "1 call/invoke expression"],
+ ["f(x);", "2 call/invoke expression"],
+ ["f(x,y);", "3 call/invoke expression"],
+ ["o.m();", "4 call/invoke expression"],
+ ["o['m'];", "5 call/invoke expression"],
+ ["o.m(x);", "6 call/invoke expression"],
+ ["o['m'](x);", "7 call/invoke expression"],
+ ["o.m(x,y);", "8 call/invoke expression"],
+ ["o['m'](x,y);", "9 call/invoke expression"],
+ ["f(x)(y);", "10 call/invoke expression"],
+ ["f().x;", "11 call/invoke expression"],
+
+ // eval
+ ["eval('x');", "1 eval"],
+ ["(eval)('x');", "2 eval"],
+ ["(1,eval)('x');", "3 eval"],
+ ["eval(x,y);", "4 eval"],
+ // new expression
+ ["new f();", "1 new expression"],
+ ["new o;", "2 new expression"],
+ ["new o.m;", "3 new expression"],
+ ["new o.m(x);", "4 new expression"],
+ ["new o.m(x,y);", "5 new expression"],
+ // prefix/postfix
+ ["++x;", "1 pre/postfix"],
+ ["x++;", "2 pre/postfix"],
+ ["--x;", "3 pre/postfix"],
+ ["x--;", "4 pre/postfix"],
+ ["x ++;", "5 pre/postfix"],
+ ["x /* comment */ ++;", "6 pre/postfix"],
+ ["++ /* comment */ x;", "7 pre/postfix"],
+ // unary operators
+ ["delete x;", "1 unary operator"],
+ ["void x;", "2 unary operator"],
+ ["+ x;", "3 unary operator"],
+ ["-x;", "4 unary operator"],
+ ["~x;", "5 unary operator"],
+ ["!x;", "6 unary operator"],
+ // meh
+ ["new Date++;", "new date ++"],
+ ["+x++;", " + x ++"],
+ // expression expressions
+ ["1 * 2;", "1 expression expressions"],
+ ["1 / 2;", "2 expression expressions"],
+ ["1 % 2;", "3 expression expressions"],
+ ["1 + 2;", "4 expression expressions"],
+ ["1 - 2;", "5 expression expressions"],
+ ["1 << 2;", "6 expression expressions"],
+ ["1 >>> 2;", "7 expression expressions"],
+ ["1 >> 2;", "8 expression expressions"],
+ ["1 * 2 + 3;", "9 expression expressions"],
+ ["(1+2)*3;", "10 expression expressions"],
+ ["1*(2+3);", "11 expression expressions"],
+ ["x<y;", "12 expression expressions"],
+ ["x>y;", "13 expression expressions"],
+ ["x<=y;", "14 expression expressions"],
+ ["x>=y;", "15 expression expressions"],
+ ["x instanceof y;", "16 expression expressions"],
+ ["x in y;", "17 expression expressions"],
+ ["x&y;", "18 expression expressions"],
+ ["x^y;", "19 expression expressions"],
+ ["x|y;", "20 expression expressions"],
+ ["x+y<z;", "21 expression expressions"],
+ ["x<y+z;", "22 expression expressions"],
+ ["x+y+z;", "23 expression expressions"],
+ ["x+y<z;", "24 expression expressions"],
+ ["x<y+z;", "25 expression expressions"],
+ ["x&y|z;", "26 expression expressions"],
+ ["x&&y;", "27 expression expressions"],
+ ["x||y;", "28 expression expressions"],
+ ["x&&y||z;", "29 expression expressions"],
+ ["x||y&&z;", "30 expression expressions"],
+ ["x<y?z:w;", "31 expression expressions"],
+ // assignment
+ ["x >>>= y;", "1 assignment"],
+ ["x <<= y;", "2 assignment"],
+ ["x = y;", "3 assignment"],
+ ["x += y;", "4 assignment"],
+ ["x /= y;", "5 assignment"],
+ // comma
+ ["x, y;", "comma"],
+ // block
+ ["{};", "1 block"],
+ ["{x;};", "2 block"],
+ ["{x;y;};", "3 block"],
+ // vars
+ ["var x;", "1 var"],
+ ["var x,y;", "2 var"],
+ ["var x=1,y=2;", "3 var"],
+ ["var x,y=2;", "4 var"],
+ // empty
+ [";", "1 empty"],
+ ["\n;", "2 empty"],
+ // expression statement
+ ["x;", "1 expression statement"],
+ ["5;", "2 expression statement"],
+ ["1+2;", "3 expression statement"],
+ // if
+ ["if (c) x; else y;", "1 if statement"],
+ ["if (c) x;", "2 if statement"],
+ ["if (c) {} else {};", "3 if statement"],
+ ["if (c1) if (c2) s1; else s2;", "4 if statement"],
+ // while
+ ["do s; while (e);", "1 while statement"],
+ ["do { s; } while (e);", "2 while statement"],
+ ["while (e) s;", "3 while statement"],
+ ["while (e) { s; };", "4 while statement"],
+ // for
+ ["for (;;) ;", "1 for statement"],
+ ["for (;c;x++) x;", "2 for statement"],
+ ["for (i;i<len;++i){};", "3 for statement"],
+ ["for (var i=0;i<len;++i) {};", "4 for statement"],
+ ["for (var i=0,j=0;;){};", "5 for statement"],
+ //["for (x in b; c; u) {};", "6 for statement"],
+ ["for ((x in b); c; u) {};", "7 for statement"],
+ ["for (x in a);", "8 for statement"],
+ ["for (var x in a){};", "9 for statement"],
+ ["for (var x=5 in a) {};", "10 for statement"],
+ ["for (var x = a in b in c) {};", "11 for statement"],
+ ["for (var x=function(){a+b;}; a<b; ++i) some;", "11 for statement, testing for parsingForHeader reset with the function"],
+ ["for (var x=function(){for (x=0; x<15; ++x) alert(foo); }; a<b; ++i) some;", "11 for statement, testing for parsingForHeader reset with the function"],
+ // flow statements
+ ["while(1){ continue; }", "1 flow statement"],
+ ["label: while(1){ continue label; }", "2 flow statement"],
+ ["while(1){ break; }", "3 flow statement"],
+ ["somewhere: while(1){ break somewhere; }", "4 flow statement"],
+ ["while(1){ continue /* comment */ ; }", "5 flow statement"],
+ ["while(1){ continue \n; }", "6 flow statement"],
+ ["(function(){ return; })()", "7 flow statement"],
+ ["(function(){ return 0; })()", "8 flow statement"],
+ ["(function(){ return 0 + \n 1; })()", "9 flow statement"],
+ // with
+ ["with (e) s;", "with statement"],
+ // switch
+ ["switch (e) { case x: s; };", "1 switch statement"],
+ ["switch (e) { case x: s1;s2; default: s3; case y: s4; };", "2 switch statement"],
+ ["switch (e) { default: s1; case x: s2; case y: s3; };", "3 switch statement"],
+ ["switch (e) { default: s; };", "4 switch statement"],
+ ["switch (e) { case x: s1; case y: s2; };", "5 switch statement"],
+ // labels
+ ["foo : x;", " flow statement"],
+ // throw
+ ["throw x;", "1 throw statement"],
+ ["throw x\n;", "2 throw statement"],
+ // try catch finally
+ ["try { s1; } catch (e) { s2; };", "1 trycatchfinally statement"],
+ ["try { s1; } finally { s2; };", "2 trycatchfinally statement"],
+ ["try { s1; } catch (e) { s2; } finally { s3; };", "3 trycatchfinally statement"],
+ // debugger
+ ["debugger;", "debugger statement"],
+ // function decl
+ ["function f(x) { e; return x; };", "1 function declaration"],
+ ["function f() { x; y; };", "2 function declaration"],
+ ["function f(x,y) { var z; return x; };", "3 function declaration"],
+ // function exp
+ ["(function f(x) { return x; });", "1 function expression"],
+ ["(function empty() {;});", "2 function expression"],
+ ["(function empty() {;});", "3 function expression"],
+ ["(function (x) {; });", "4 function expression"],
+ // program
+ ["var x; function f(){;}; null;", "1 program"],
+ [";;", "2 program"],
+ ["{ x; y; z; }", "3 program"],
+ ["function f(){ function g(){;}};", "4 program"],
+ ["x;\n/*foo*/\n ;", "5 program"],
+
+ // asi
+ ["foo: while(1){ continue \n foo; }", "1 asi"],
+ ["foo: while(1){ break \n foo; }", "2 asi"],
+ ["(function(){ return\nfoo; })()", "3 asi"],
+ ["var x; { 1 \n 2 } 3", "4 asi"],
+ ["ab /* hi */\ncd", "5 asi"],
+ ["ab/*\n*/cd", "6 asi (multi line multilinecomment counts as eol)"],
+ ["foo: while(1){ continue /* wtf \n busta */ foo; }", "7 asi illegal with multi line comment"],
+ ["function f() { s }", "8 asi"],
+ ["function f() { return }", "9 asi"],
+
+ // use strict
+ // XXX: some of these should actually fail?
+ // no support for "use strict" yet...
+ ['"use strict"; \'bla\'\n; foo;', "1 directive"],
+ ['(function() { "use strict"; \'bla\';\n foo; });', "2 directive"],
+ ['"use\\n strict";', "3 directive"],
+ ['foo; "use strict";', "4 directive"],
+
+ // tests from http://es5conform.codeplex.com/
+
+ ['"use strict"; var o = { eval: 42};', "8.7.2-3-1-s: the use of eval as property name is allowed"],
+ ['({foo:0,foo:1});', 'Duplicate property name allowed in not strict mode'],
+ ['function foo(a,a){}', 'Duplicate parameter name allowed in not strict mode'],
+ ['(function foo(eval){})', 'Eval allowed as parameter name in non strict mode'],
+ ['(function foo(arguments){})', 'Arguments allowed as parameter name in non strict mode'],
+
+ // empty programs
+
+ ['', '1 Empty program'],
+ ['// test', '2 Empty program'],
+ ['//test\n', '3 Empty program'],
+ ['\n// test', '4 Empty program'],
+ ['\n// test\n', '5 Empty program'],
+ ['/* */', '6 Empty program'],
+ ['/*\ns,fd\n*/', '7 Empty program'],
+ ['/*\ns,fd\n*/\n', '8 Empty program'],
+ [' ', '9 Empty program'],
+ [' /*\nsmeh*/ \n ', '10 Empty program'],
+
+ // trailing whitespace
+
+ ['a ', '1 Trailing whitespace'],
+ ['a /* something */', '2 Trailing whitespace'],
+ ['a\n // hah', '3 Trailing whitespace'],
+ ['/abc/de//f', '4 Trailing whitespace'],
+ ['/abc/de/*f*/\n ', '5 Trailing whitespace'],
+
+ // things the parser tripped over at one point or the other (prevents regression bugs)
+ ['for (x;function(){ a\nb };z) x;', 'for header with function body forcing ASI'],
+ ['c=function(){return;return};', 'resetting noAsi after literal'],
+ ['d\nd()', 'asi exception causing token overflow'],
+ ['for(;;){x=function(){}}', 'function expression in a for header'],
+ ['for(var k;;){}', 'parser failing due to ASI accepting the incorrect "for" rule'],
+ ['({get foo(){ }})', 'getter with empty function body'],
+ ['\nreturnr', 'eol causes return statement to ignore local search requirement'],
+ [' / /', '1 whitespace before regex causes regex to fail?'],
+ ['/ // / /', '2 whitespace before regex causes regex to fail?'],
+ ['/ / / / /', '3 whitespace before regex causes regex to fail?'],
+
+ ['\n\t// Used for trimming whitespace\n\ttrimLeft = /^\\s+/;\n\ttrimRight = /\\s+$/;\t\n','turned out this didnt crash (the test below did), but whatever.'],
+ ['/[\\/]/;', 'escaped forward slash inside class group (would choke on fwd slash)'],
+ ['/[/]/;', 'also broke but is valid in es5 (not es3)'],
+ ['({get:5});','get property name thats not a getter'],
+ ['({set:5});','set property name thats not a setter'],
+ ['l !== "px" && (d.style(h, c, (k || 1) + l), j = (k || 1) / f.cur() * j, d.style(h, c, j + l)), i[1] && (k = (i[1] === "-=" ? -1 : 1) * k + j), f.custom(j, k, l)', 'this choked regex/div at some point'],
+ ['(/\'/g, \'\\\\\\\'\') + "\'";', 'the sequence of escaped characters confused the tokenizer'],
+ ['if (true) /=a/.test("a");', 'regexp starting with "=" in not obvious context (not implied by preceding token)']
+ ];
+
+ for (var i=0; i<inps.length; ++i) {
+ callback(i, inps[i][0], inps[i][1]);
+ };
+};
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/testparser.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedarray1js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array1.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array1.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array1.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+[],Array(1),[1,2,3]
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedarray2js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array2.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array2.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array2.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+(function(){var a=function(){};return new a(1,2,3,4)})()
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedarray3js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array3.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array3.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array3.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+(function(){function a(){}return new a(1,2,3,4)})()
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedarray4js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array4.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array4.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/array4.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+(function(){function a(){}(function(){return new a(1,2,3)})()})()
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedassignmentjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/assignment.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/assignment.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/assignment.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+a=1,b=a,c=1,d=b,e=d,longname=2;if(longname+1){x=3;if(x)var z=7}z=1,y=1,x=1,g+=1,h=g,++i,j=i,i++,j=i+17
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedconcatstringjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/concatstring.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/concatstring.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/concatstring.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a=a+"a"+"b"+1+c,b=a+"c"+"ds"+123+c,c=a+"c"+123+d+"ds"+c
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedconstjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/const.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/const.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/const.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a=13,b=1/3
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedemptyblocksjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/empty-blocks.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/empty-blocks.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/empty-blocks.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+function bar(){return--x}function foo(){while(bar());}function mak(){for(;;);}var x=5
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedforstatementjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/forstatement.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/forstatement.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/forstatement.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+a=func(),b=z;for(a++;i<10;i++)alert(i);var z=1;g=2;for(;i<10;i++)alert(i);var a=2;for(var i=1;i<10;i++)alert(i)
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedifjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/if.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/if.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/if.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a=1;a==1?a=2:a=17
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedifreturnjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/ifreturn.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/ifreturn.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/ifreturn.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+function a(a){return a==1?2:17}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedifreturn2js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/ifreturn2.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/ifreturn2.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/ifreturn2.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+function x(a){return typeof a=="object"?a:a===42?0:a*2}function y(a){return typeof a=="object"?a:null}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue10js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue10.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue10.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue10.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+function f(){var a;return(a="a")?a:a}f()
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue11js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue11.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue11.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue11.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+new(A,B),new(A||B),new(X?A:B)
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue13js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue13.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue13.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue13.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a=/^(?:(\w+):)?(?:\/\/(?:(?:([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#])(?::(\d))?)?(..?$|(?:[^?#\/]\/))([^?#]*)(?:\?([^#]))?(?:#(.))?/
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue14js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue14.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue14.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue14.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue16js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue16.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue16.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue16.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a=3250441966
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue17js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue17.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue17.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue17.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a=function(b){b(),a()}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue20js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue20.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue20.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue20.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+1
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue21js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue21.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue21.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue21.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a=0;switch(a){case 0:a++}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue25js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue25.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue25.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue25.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+a:break a;console.log(1)
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue27js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue27.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue27.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue27.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+(a?b:c)?d:e
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue278js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue278.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue278.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue278.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+if(!x)debugger
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue28js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue28.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue28.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue28.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+o={".5":.5},o={.5:.5},o={.5:.5}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue29js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue29.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue29.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue29.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+result=function(){return 1}()
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue30js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue30.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue30.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue30.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a=8,b=4,c=4
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue34js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue34.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue34.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue34.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a={};a["this"]=1,a.that=2
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue4js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue4.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue4.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue4.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a=2e3,b=.002,c=2e-5
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue48js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue48.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue48.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue48.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var s,i;s="",i=0
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue50js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue50.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue50.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue50.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+function bar(a){try{foo()}catch(b){alert("Exception caught (foo not defined)")}alert(a)}bar(10)
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue53js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue53.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue53.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue53.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+x=(y,z)
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue541js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue54.1.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue54.1.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue54.1.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+foo+"",a.toString(16),b.toString.call(c)
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue68js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue68.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue68.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue68.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+function f(){function b(){}if(a)return;b()}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue69js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue69.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue69.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue69.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+[(a,b)]
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedissue9js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue9.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue9.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/issue9.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a={a:1,b:2}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedmanglejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/mangle.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/mangle.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/mangle.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+(function(){var a=function b(a,b,c){return b}})()
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectednull_stringjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/null_string.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/null_string.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/null_string.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var nullString="\0"
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedstrictequalsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/strict-equals.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/strict-equals.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/strict-equals.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+typeof a=="string",b+""!=c+"",d<e==f<g
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedvarjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/var.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/var.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/var.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a=1,b=2
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedwhitespacejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/whitespace.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/whitespace.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/whitespace.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+function id(a){return a}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressexpectedwithjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/with.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/with.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/expected/with.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+with({});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestarray1js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array1.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array1.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array1.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+new Array();
+new Array(1);
+new Array(1, 2, 3);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestarray2js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array2.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array2.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array2.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+(function(){
+ var Array = function(){};
+ return new Array(1, 2, 3, 4);
+})();
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestarray3js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array3.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array3.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array3.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+(function(){
+ return new Array(1, 2, 3, 4);
+ function Array() {};
+})();
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestarray4js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array4.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array4.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/array4.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+(function(){
+ (function(){
+ return new Array(1, 2, 3);
+ })();
+ function Array(){};
+})();
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestassignmentjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/assignment.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/assignment.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/assignment.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+a=1;
+b=a;
+c=1;
+d=b;
+e=d;
+longname=2;
+if (longname+1) {
+ x=3;
+ if (x) var z = 7;
+}
+z=1,y=1,x=1
+
+g+=1;
+h=g;
+
+++i;
+j=i;
+
+i++;
+j=i+17;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestconcatstringjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/concatstring.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/concatstring.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/concatstring.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+var a = a + "a" + "b" + 1 + c;
+var b = a + "c" + "ds" + 123 + c;
+var c = a + "c" + 123 + d + "ds" + c;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestconstjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/const.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/const.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/const.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+// test that the calculation is fold to 13
+var a = 1 + 2 * 6;
+
+// test that it isn't replaced with 0.3333 because that is more characters
+var b = 1/3;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestemptyblocksjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/empty-blocks.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/empty-blocks.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/empty-blocks.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+var x = 5;
+function bar() { return --x; }
+function foo() { while (bar()); }
+function mak() { for(;;); }
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestforstatementjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/forstatement.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/forstatement.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/forstatement.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+a=func();
+b=z;
+for (a++; i < 10; i++) { alert(i); }
+
+var z=1;
+g=2;
+for (; i < 10; i++) { alert(i); }
+
+var a = 2;
+for (var i = 1; i < 10; i++) { alert(i); }
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestifjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/if.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/if.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/if.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+var a = 1;
+if (a == 1) {
+ a = 2;
+} else {
+ a = 17;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestifreturnjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/ifreturn.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/ifreturn.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/ifreturn.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+function a(b) {
+ if (b == 1) {
+ return 2;
+ } else {
+ return 17;
+ }
+
+ return 3;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestifreturn2js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/ifreturn2.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/ifreturn2.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/ifreturn2.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function x(a) {
+ if (typeof a === 'object')
+ return a;
+
+ if (a === 42)
+ return 0;
+
+ return a * 2;
+}
+
+function y(a) {
+ if (typeof a === 'object')
+ return a;
+
+ return null;
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue10js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue10.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue10.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue10.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+function f() { var a; if (a = 'a') { return a; } else { return a; } }; f();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue11js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue11.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue11.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue11.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+new (A, B)
+new (A || B)
+new (X ? A : B)
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue13js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue13.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue13.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue13.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a = /^(?:(\w+):)?(?:\/\/(?:(?:([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#])(?::(\d))?)?(..?$|(?:[^?#\/]\/))([^?#]*)(?:\?([^#]))?(?:#(.))?/;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue14js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue14.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue14.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue14.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'};
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue16js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue16.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue16.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue16.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var a = 0xC1BDCEEE;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue17js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue17.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue17.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue17.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+var a = function(b) {
+ b();
+ a()
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue20js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue20.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue20.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue20.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+{a: 1}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue21js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue21.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue21.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue21.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+var a = 0;
+switch(a) {
+ case 0:
+ a++;
+ break;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue25js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue25.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue25.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue25.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+label1 : {
+ label2 : {
+ break label2;
+ console.log(2);
+ }
+ console.log(1);
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue27js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue27.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue27.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue27.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+(a ? b : c) ? d : e
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue278js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue278.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue278.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue278.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+if (!x) debugger;
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue28js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue28.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue28.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue28.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+o = {'.5':.5}
+o = {'0.5':.5}
+o = {0.5:.5}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue29js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue29.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue29.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue29.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+result=(function(){ return 1;})()
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue30js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue30.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue30.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue30.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+var a = 1 << 3;
+var b = 8 >> 1;
+var c = 8 >>> 1;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue34js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue34.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue34.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue34.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+var a = {};
+a["this"] = 1;
+a["that"] = 2;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue4js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue4.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue4.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue4.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+var a = 2e3;
+var b = 2e-3;
+var c = 2e-5;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue48js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue48.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue48.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue48.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var s, i; s = ''; i = 0;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue50js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue50.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue50.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue50.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+function bar(a) {
+ try {
+ foo();
+ } catch(e) {
+ alert("Exception caught (foo not defined)");
+ }
+ alert(a); // 10 in FF, "[object Error]" in IE
+}
+bar(10);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue53js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue53.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue53.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue53.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+x = (y, z)
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue541js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue54.1.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue54.1.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue54.1.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+foo.toString();
+a.toString(16);
+b.toString.call(c);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue68js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue68.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue68.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue68.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+function f() {
+ if (a) return;
+ g();
+ function g(){}
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue69js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue69.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue69.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue69.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+[(a,b)]
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestissue9js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue9.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue9.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/issue9.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+var a = {
+ a: 1,
+ b: 2, // <-- trailing comma
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestmanglejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/mangle.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/mangle.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/mangle.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+(function() {
+ var x = function fun(a, fun, b) {
+ return fun;
+ };
+}());
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestnull_stringjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/null_string.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/null_string.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/null_string.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+var nullString = "\0"
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompressteststrictequalsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/strict-equals.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/strict-equals.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/strict-equals.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+typeof a === 'string'
+b + "" !== c + ""
+d < e === f < g
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestvarjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/var.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/var.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/var.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+// var declarations after each other should be combined
+var a = 1;
+var b = 2;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestwhitespacejs"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/whitespace.js</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/whitespace.js
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/whitespace.js 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/whitespace.js 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/whitespace.js
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+application/octet-stream
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitcompresstestwithjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/with.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/with.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/compress/test/with.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+with({}) {
+};
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstestunitscriptsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/scripts.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/scripts.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/test/unit/scripts.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+global.DIGITS_OVERRIDE_FOR_TESTING = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
+
+var fs = require('fs'),
+ uglify = require('../../uglify-js'),
+ jsp = uglify.parser,
+ nodeunit = require('nodeunit'),
+ path = require('path'),
+ pro = uglify.uglify;
+
+var Script = process.binding('evals').Script;
+
+var scriptsPath = __dirname;
+
+function compress(code) {
+ var ast = jsp.parse(code);
+ ast = pro.ast_mangle(ast, { mangle: true });
+ ast = pro.ast_squeeze(ast, { no_warnings: true });
+ ast = pro.ast_squeeze_more(ast);
+ return pro.gen_code(ast);
+};
+
+var testDir = path.join(scriptsPath, "compress", "test");
+var expectedDir = path.join(scriptsPath, "compress", "expected");
+
+function getTester(script) {
+ return function(test) {
+ var testPath = path.join(testDir, script);
+ var expectedPath = path.join(expectedDir, script);
+ var content = fs.readFileSync(testPath, 'utf-8');
+ var outputCompress = compress(content);
+
+ // Check if the noncompressdata is larger or same size as the compressed data
+ test.ok(content.length >= outputCompress.length);
+
+ // Check that a recompress gives the same result
+ var outputReCompress = compress(content);
+ test.equal(outputCompress, outputReCompress);
+
+ // Check if the compressed output is what is expected
+ var expected = fs.readFileSync(expectedPath, 'utf-8');
+ test.equal(outputCompress, expected.replace(/(\r?\n)+$/, ""));
+
+ test.done();
+ };
+};
+
+var tests = {};
+
+var scripts = fs.readdirSync(testDir);
+for (var i in scripts) {
+ var script = scripts[i];
+ if (/\.js$/.test(script)) {
+ tests[script] = getTester(script);
+ }
+}
+
+module.exports = nodeunit.testCase(tests);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstmphoistjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/hoist.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/hoist.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/hoist.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+function foo(arg1, arg2, arg3, arg4, arg5, arg6) {
+ var a = 5;
+ {
+ var d = 10, mak = 20, buz = 30;
+ var q = buz * 2;
+ }
+ if (moo) {
+ var a, b, c;
+ }
+ for (var arg1 = 0, d = 20; arg1 < 10; ++arg1)
+ console.log(arg3);
+ for (var i in mak) {}
+ for (j in d) {}
+ var d;
+
+ function test() {
+
+ };
+
+ //test();
+
+ (function moo(first, second){
+ console.log(first);
+ })(1);
+
+ (function moo(first, second){
+ console.log(moo());
+ })(1);
+}
+
+
+var foo;
+var bar;
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstmpinstrumentjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/instrument.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/instrument.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/instrument.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,97 @@
</span><ins>+// sample on how to use the parser and walker API to instrument some code
+
+var jsp = require("uglify-js").parser;
+var pro = require("uglify-js").uglify;
+
+function instrument(code) {
+ var ast = jsp.parse(code, false, true); // true for the third arg specifies that we want
+ // to have start/end tokens embedded in the
+ // statements
+ var w = pro.ast_walker();
+
+ // we're gonna need this to push elements that we're currently looking at, to avoid
+ // endless recursion.
+ var analyzing = [];
+ function do_stat() {
+ var ret;
+ if (this[0].start && analyzing.indexOf(this) < 0) {
+ // without the `analyzing' hack, w.walk(this) would re-enter here leading
+ // to infinite recursion
+ analyzing.push(this);
+ ret = [ "splice", // XXX: "block" is safer
+ [ [ "stat",
+ [ "call", [ "name", "trace" ],
+ [ [ "string", this[0].toString() ],
+ [ "num", this[0].start.line ],
+ [ "num", this[0].start.col ],
+ [ "num", this[0].end.line ],
+ [ "num", this[0].end.col ]]]],
+ w.walk(this) ]];
+ analyzing.pop(this);
+ }
+ return ret;
+ };
+ var new_ast = w.with_walkers({
+ "stat" : do_stat,
+ "label" : do_stat,
+ "break" : do_stat,
+ "continue" : do_stat,
+ "debugger" : do_stat,
+ "var" : do_stat,
+ "const" : do_stat,
+ "return" : do_stat,
+ "throw" : do_stat,
+ "try" : do_stat,
+ "defun" : do_stat,
+ "if" : do_stat,
+ "while" : do_stat,
+ "do" : do_stat,
+ "for" : do_stat,
+ "for-in" : do_stat,
+ "switch" : do_stat,
+ "with" : do_stat
+ }, function(){
+ return w.walk(ast);
+ });
+ return pro.gen_code(new_ast, { beautify: true });
+}
+
+
+
+
+////// test code follows.
+
+var code = instrument(test.toString());
+console.log(code);
+
+function test() {
+ // simple stats
+ a = 5;
+ c += a + b;
+ "foo";
+
+ // var
+ var foo = 5;
+ const bar = 6, baz = 7;
+
+ // switch block. note we can't track case lines the same way.
+ switch ("foo") {
+ case "foo":
+ return 1;
+ case "bar":
+ return 2;
+ }
+
+ // for/for in
+ for (var i = 0; i < 5; ++i) {
+ console.log("Hello " + i);
+ }
+ for (var i in [ 1, 2, 3]) {
+ console.log(i);
+ }
+
+ // note however that the following is broken. I guess we
+ // should add the block brackets in this case...
+ for (var i = 0; i < 5; ++i)
+ console.log("foo");
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjstmptestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/test.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/test.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/test.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+#! /usr/bin/env node
+
+global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util");
+var fs = require("fs");
+var uglify = require("uglify-js"), // symlink ~/.node_libraries/uglify-js.js to ../uglify-js.js
+ jsp = uglify.parser,
+ pro = uglify.uglify;
+
+var code = fs.readFileSync("hoist.js", "utf8");
+var ast = jsp.parse(code);
+
+ast = pro.ast_lift_variables(ast);
+
+var w = pro.ast_walker();
+ast = w.with_walkers({
+ "function": function() {
+ var node = w.dive(this); // walk depth first
+ console.log(pro.gen_code(node, { beautify: true }));
+ return node;
+ },
+ "name": function(name) {
+ return [ this[0], "X" ];
+ }
+}, function(){
+ return w.walk(ast);
+});
+
+console.log(pro.gen_code(ast, {
+ beautify: true
+}));
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/tmp/test.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsminifiernode_modulesuglifyjsuglifyjsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/uglify-js.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/uglify-js.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/uglify-js/uglify-js.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+//convienence function(src, [options]);
+function uglify(orig_code, options){
+ options || (options = {});
+ var jsp = uglify.parser;
+ var pro = uglify.uglify;
+
+ var ast = jsp.parse(orig_code, options.strict_semicolons); // parse code and get the initial AST
+ ast = pro.ast_mangle(ast, options.mangle_options); // get a new AST with mangled names
+ ast = pro.ast_squeeze(ast, options.squeeze_options); // get an AST with compression optimizations
+ var final_code = pro.gen_code(ast, options.gen_options); // compressed code here
+ return final_code;
+};
+
+uglify.parser = require("./lib/parse-js");
+uglify.uglify = require("./lib/process");
+uglify.consolidator = require("./lib/consolidator");
+
+module.exports = uglify
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifiernode_moduleswalkerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/walker.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/walker.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/node_modules/walker.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+var fs = require("fs");
+
+//
+// setup DOM-like sandbox
+//
+
+var window = {};
+var loader;
+
+var script = function(inPath) {
+ eval(fs.readFileSync(inPath, "utf8"));
+};
+
+module.exports = {
+ init: function(inEnyoPath) {
+ script(inEnyoPath + "/loader.js");
+ enyo.path.addPaths({
+ enyo: inEnyoPath,
+ lib: inEnyoPath + "/../lib"
+ });
+ loader = new enyo.loaderFactory({
+ script: function() {},
+ sheet: function() {}
+ });
+ loader.loadPackage = function(inScript) {
+ script(inScript);
+ };
+ enyo.depends = function() {
+ //console.log(arguments);
+ loader.load.apply(loader, arguments);
+ };
+ },
+ walk: function(inScript, inCallback) {
+ //console.log("walking: ", inScript);
+ loader.finish = function() {
+ inCallback(loader);
+ };
+ script(enyo.path.rewrite(inScript));
+ }
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifierpathrelativeshimjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minifier/path-relative-shim.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minifier/path-relative-shim.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minifier/path-relative-shim.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,135 @@
</span><ins>+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+/*
+
+ path.relative shim for older versions of node
+
+*/
+
+var isWindows = process.platform === 'win32';
+var path = require('path');
+
+if (isWindows) {
+
+ // path.relative(from, to)
+ // it will solve the relative path from 'from' to 'to', for instance:
+ // from = 'C:\\orandea\\test\\aaa'
+ // to = 'C:\\orandea\\impl\\bbb'
+ // The output of the function should be: '..\\..\\impl\\bbb'
+ // windows version
+ exports.relative = function(from, to) {
+ from = path.resolve(from);
+ to = path.resolve(to);
+
+ // windows is not case sensitive
+ var lowerFrom = from.toLowerCase();
+ var lowerTo = to.toLowerCase();
+
+ function trim(arr) {
+ var start = 0;
+ for (; start < arr.length; start++) {
+ if (arr[start] !== '') break;
+ }
+
+ var end = arr.length - 1;
+ for (; end >= 0; end--) {
+ if (arr[end] !== '') break;
+ }
+
+ if (start > end) return [];
+ return arr.slice(start, end - start + 1);
+ }
+
+ var toParts = trim(to.split('\\'));
+
+ var lowerFromParts = trim(lowerFrom.split('\\'));
+ var lowerToParts = trim(lowerTo.split('\\'));
+
+ var length = Math.min(lowerFromParts.length, lowerToParts.length);
+ var samePartsLength = length;
+ for (var i = 0; i < length; i++) {
+ if (lowerFromParts[i] !== lowerToParts[i]) {
+ samePartsLength = i;
+ break;
+ }
+ }
+
+ if (samePartsLength == 0) {
+ return to;
+ }
+
+ var outputParts = [];
+ for (var i = samePartsLength; i < lowerFromParts.length; i++) {
+ outputParts.push('..');
+ }
+
+ outputParts = outputParts.concat(toParts.slice(samePartsLength));
+
+ return outputParts.join('\\');
+ };
+
+} else /* posix */ {
+
+ // path.relative(from, to)
+ // posix version
+ exports.relative = function(from, to) {
+ from = path.resolve(from).substr(1);
+ to = path.resolve(to).substr(1);
+
+ function trim(arr) {
+ var start = 0;
+ for (; start < arr.length; start++) {
+ if (arr[start] !== '') break;
+ }
+
+ var end = arr.length - 1;
+ for (; end >= 0; end--) {
+ if (arr[end] !== '') break;
+ }
+
+ if (start > end) return [];
+ return arr.slice(start, end - start + 1);
+ }
+
+ var fromParts = trim(from.split('/'));
+ var toParts = trim(to.split('/'));
+
+ var length = Math.min(fromParts.length, toParts.length);
+ var samePartsLength = length;
+ for (var i = 0; i < length; i++) {
+ if (fromParts[i] !== toParts[i]) {
+ samePartsLength = i;
+ break;
+ }
+ }
+
+ var outputParts = [];
+ for (var i = samePartsLength; i < fromParts.length; i++) {
+ outputParts.push('..');
+ }
+
+ outputParts = outputParts.concat(toParts.slice(samePartsLength));
+
+ return outputParts.join('/');
+ };
+
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifybat"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minify.bat (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minify.bat (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minify.bat 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+REM don't watch the sausage being made
+@ECHO OFF
+
+REM the folder this script is in (*/enyo/tools)
+SET TOOLS=%~DP0
+
+REM enyo location
+SET ENYO=%TOOLS%\..
+
+REM minify script location
+SET MINIFY=%TOOLS%\minifier\minify.js
+
+REM node location
+SET NODE=node.exe
+
+REM use node to invoke minify with a known path to enyo and imported parameters
+%NODE% "%MINIFY%" -enyo "%ENYO%" %*
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsminifysh"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/minify.sh (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/minify.sh (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/minify.sh 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+#!/bin/bash
+
+# the folder this script is in (*/enyo/tools)
+TOOLS="$(cd `dirname $0`; pwd)"
+# enyo location
+ENYO="$TOOLS/.."
+# minify script location
+MINIFY="$TOOLS/minifier/minify.js"
+
+# check for node, but quietly
+if command -v node >/dev/null 2>&1; then
+ # use node to invoke minify with a known path to enyo and imported parameters
+ echo "enyo/tools/minify.sh args: " $@
+ node "$MINIFY" -enyo "$ENYO" $@
+else
+ echo "No node found in path"
+ exit 1
+fi
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/minify.sh
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsnode_modulesbinnopt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/.bin/nopt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/.bin/nopt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/.bin/nopt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+#!/usr/bin/env node
+var nopt = require("../lib/nopt")
+ , types = { num: Number
+ , bool: Boolean
+ , help: Boolean
+ , list: Array
+ , "num-list": [Number, Array]
+ , "str-list": [String, Array]
+ , "bool-list": [Boolean, Array]
+ , str: String }
+ , shorthands = { s: [ "--str", "astring" ]
+ , b: [ "--bool" ]
+ , nb: [ "--no-bool" ]
+ , tft: [ "--bool-list", "--no-bool-list", "--bool-list", "true" ]
+ , "?": ["--help"]
+ , h: ["--help"]
+ , H: ["--help"]
+ , n: [ "--num", "125" ] }
+ , parsed = nopt( types
+ , shorthands
+ , process.argv
+ , 2 )
+
+console.log("parsed", parsed)
+
+if (parsed.help) {
+ console.log("")
+ console.log("nopt cli tester")
+ console.log("")
+ console.log("types")
+ console.log(Object.keys(types).map(function M (t) {
+ var type = types[t]
+ if (Array.isArray(type)) {
+ return [t, type.map(function (type) { return type.name })]
+ }
+ return [t, type && type.name]
+ }).reduce(function (s, i) {
+ s[i[0]] = i[1]
+ return s
+ }, {}))
+ console.log("")
+ console.log("shorthands")
+ console.log(shorthands)
+}
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/node_modules/.bin/nopt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsnode_modulesbinshjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/.bin/shjs (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/.bin/shjs (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/.bin/shjs 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+#!/usr/bin/env node
+require('../global');
+
+if (process.argv.length < 3) {
+ console.log('ShellJS: missing argument (script name)');
+ console.log();
+ process.exit(1);
+}
+
+var scriptName = process.argv[2];
+env['NODE_PATH'] = __dirname + '/../..';
+
+if (!scriptName.match(/\.js/) && !scriptName.match(/\.coffee/)) {
+ if (test('-f', scriptName + '.js'))
+ scriptName += '.js';
+ if (test('-f', scriptName + '.coffee'))
+ scriptName += '.coffee';
+}
+
+if (!test('-f', scriptName)) {
+ console.log('ShellJS: script not found ('+scriptName+')');
+ console.log();
+ process.exit(1);
+}
+
+
+if (scriptName.match(/\.coffee$/)) {
+ //
+ // CoffeeScript
+ //
+ if (which('coffee')) {
+ exec('coffee ' + scriptName, { async: true });
+ } else {
+ console.log('ShellJS: CoffeeScript interpreter not found');
+ console.log();
+ process.exit(1);
+ }
+} else {
+ //
+ // JavaScript
+ //
+ exec('node ' + scriptName, { async: true });
+}
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/node_modules/.bin/shjs
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsnode_modulesnoptnpmignore"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/.npmignore ( => )</h4>
<pre class="diff"><span>
<span class="info">Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/LICENSE
===================================================================
</span><del>--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/LICENSE (rev 0)
</del><ins>+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/LICENSE 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesnoptREADMEmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/README.md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/README.md (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/README.md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,210 @@
</span><ins>+If you want to write an option parser, and have it be good, there are
+two ways to do it. The Right Way, and the Wrong Way.
+
+The Wrong Way is to sit down and write an option parser. We've all done
+that.
+
+The Right Way is to write some complex configurable program with so many
+options that you go half-insane just trying to manage them all, and put
+it off with duct-tape solutions until you see exactly to the core of the
+problem, and finally snap and write an awesome option parser.
+
+If you want to write an option parser, don't write an option parser.
+Write a package manager, or a source control system, or a service
+restarter, or an operating system. You probably won't end up with a
+good one of those, but if you don't give up, and you are relentless and
+diligent enough in your procrastination, you may just end up with a very
+nice option parser.
+
+## USAGE
+
+ // my-program.js
+ var nopt = require("nopt")
+ , Stream = require("stream").Stream
+ , path = require("path")
+ , knownOpts = { "foo" : [String, null]
+ , "bar" : [Stream, Number]
+ , "baz" : path
+ , "bloo" : [ "big", "medium", "small" ]
+ , "flag" : Boolean
+ , "pick" : Boolean
+ , "many" : [String, Array]
+ }
+ , shortHands = { "foofoo" : ["--foo", "Mr. Foo"]
+ , "b7" : ["--bar", "7"]
+ , "m" : ["--bloo", "medium"]
+ , "p" : ["--pick"]
+ , "f" : ["--flag"]
+ }
+ // everything is optional.
+ // knownOpts and shorthands default to {}
+ // arg list defaults to process.argv
+ // slice defaults to 2
+ , parsed = nopt(knownOpts, shortHands, process.argv, 2)
+ console.log(parsed)
+
+This would give you support for any of the following:
+
+```bash
+$ node my-program.js --foo "blerp" --no-flag
+{ "foo" : "blerp", "flag" : false }
+
+$ node my-program.js ---bar 7 --foo "Mr. Hand" --flag
+{ bar: 7, foo: "Mr. Hand", flag: true }
+
+$ node my-program.js --foo "blerp" -f -----p
+{ foo: "blerp", flag: true, pick: true }
+
+$ node my-program.js -fp --foofoo
+{ foo: "Mr. Foo", flag: true, pick: true }
+
+$ node my-program.js --foofoo -- -fp # -- stops the flag parsing.
+{ foo: "Mr. Foo", argv: { remain: ["-fp"] } }
+
+$ node my-program.js --blatzk 1000 -fp # unknown opts are ok.
+{ blatzk: 1000, flag: true, pick: true }
+
+$ node my-program.js --blatzk true -fp # but they need a value
+{ blatzk: true, flag: true, pick: true }
+
+$ node my-program.js --no-blatzk -fp # unless they start with "no-"
+{ blatzk: false, flag: true, pick: true }
+
+$ node my-program.js --baz b/a/z # known paths are resolved.
+{ baz: "/Users/isaacs/b/a/z" }
+
+# if Array is one of the types, then it can take many
+# values, and will always be an array. The other types provided
+# specify what types are allowed in the list.
+
+$ node my-program.js --many 1 --many null --many foo
+{ many: ["1", "null", "foo"] }
+
+$ node my-program.js --many foo
+{ many: ["foo"] }
+```
+
+Read the tests at the bottom of `lib/nopt.js` for more examples of
+what this puppy can do.
+
+## Types
+
+The following types are supported, and defined on `nopt.typeDefs`
+
+* String: A normal string. No parsing is done.
+* path: A file system path. Gets resolved against cwd if not absolute.
+* url: A url. If it doesn't parse, it isn't accepted.
+* Number: Must be numeric.
+* Date: Must parse as a date. If it does, and `Date` is one of the options,
+ then it will return a Date object, not a string.
+* Boolean: Must be either `true` or `false`. If an option is a boolean,
+ then it does not need a value, and its presence will imply `true` as
+ the value. To negate boolean flags, do `--no-whatever` or `--whatever
+ false`
+* NaN: Means that the option is strictly not allowed. Any value will
+ fail.
+* Stream: An object matching the "Stream" class in node. Valuable
+ for use when validating programmatically. (npm uses this to let you
+ supply any WriteStream on the `outfd` and `logfd` config options.)
+* Array: If `Array` is specified as one of the types, then the value
+ will be parsed as a list of options. This means that multiple values
+ can be specified, and that the value will always be an array.
+
+If a type is an array of values not on this list, then those are
+considered valid values. For instance, in the example above, the
+`--bloo` option can only be one of `"big"`, `"medium"`, or `"small"`,
+and any other value will be rejected.
+
+When parsing unknown fields, `"true"`, `"false"`, and `"null"` will be
+interpreted as their JavaScript equivalents, and numeric values will be
+interpreted as a number.
+
+You can also mix types and values, or multiple types, in a list. For
+instance `{ blah: [Number, null] }` would allow a value to be set to
+either a Number or null. When types are ordered, this implies a
+preference, and the first type that can be used to properly interpret
+the value will be used.
+
+To define a new type, add it to `nopt.typeDefs`. Each item in that
+hash is an object with a `type` member and a `validate` method. The
+`type` member is an object that matches what goes in the type list. The
+`validate` method is a function that gets called with `validate(data,
+key, val)`. Validate methods should assign `data[key]` to the valid
+value of `val` if it can be handled properly, or return boolean
+`false` if it cannot.
+
+You can also call `nopt.clean(data, types, typeDefs)` to clean up a
+config object and remove its invalid properties.
+
+## Error Handling
+
+By default, nopt outputs a warning to standard error when invalid
+options are found. You can change this behavior by assigning a method
+to `nopt.invalidHandler`. This method will be called with
+the offending `nopt.invalidHandler(key, val, types)`.
+
+If no `nopt.invalidHandler` is assigned, then it will console.error
+its whining. If it is assigned to boolean `false` then the warning is
+suppressed.
+
+## Abbreviations
+
+Yes, they are supported. If you define options like this:
+
+```javascript
+{ "foolhardyelephants" : Boolean
+, "pileofmonkeys" : Boolean }
+```
+
+Then this will work:
+
+```bash
+node program.js --foolhar --pil
+node program.js --no-f --pileofmon
+# etc.
+```
+
+## Shorthands
+
+Shorthands are a hash of shorter option names to a snippet of args that
+they expand to.
+
+If multiple one-character shorthands are all combined, and the
+combination does not unambiguously match any other option or shorthand,
+then they will be broken up into their constituent parts. For example:
+
+```json
+{ "s" : ["--loglevel", "silent"]
+, "g" : "--global"
+, "f" : "--force"
+, "p" : "--parseable"
+, "l" : "--long"
+}
+```
+
+```bash
+npm ls -sgflp
+# just like doing this:
+npm ls --loglevel silent --global --force --long --parseable
+```
+
+## The Rest of the args
+
+The config object returned by nopt is given a special member called
+`argv`, which is an object with the following fields:
+
+* `remain`: The remaining args after all the parsing has occurred.
+* `original`: The args as they originally appeared.
+* `cooked`: The args after flags and shorthands are expanded.
+
+## Slicing
+
+Node programs are called with more or less the exact argv as it appears
+in C land, after the v8 and node-specific options have been plucked off.
+As such, `argv[0]` is always `node` and `argv[1]` is always the
+JavaScript program being run.
+
+That's usually not very useful to you. So they're sliced off by
+default. If you want them, then you can pass in `0` as the last
+argument, or any other number that you'd like to slice off the start of
+the list.
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesnoptbinnoptjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/bin/nopt.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/bin/nopt.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/bin/nopt.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+#!/usr/bin/env node
+var nopt = require("../lib/nopt")
+ , types = { num: Number
+ , bool: Boolean
+ , help: Boolean
+ , list: Array
+ , "num-list": [Number, Array]
+ , "str-list": [String, Array]
+ , "bool-list": [Boolean, Array]
+ , str: String }
+ , shorthands = { s: [ "--str", "astring" ]
+ , b: [ "--bool" ]
+ , nb: [ "--no-bool" ]
+ , tft: [ "--bool-list", "--no-bool-list", "--bool-list", "true" ]
+ , "?": ["--help"]
+ , h: ["--help"]
+ , H: ["--help"]
+ , n: [ "--num", "125" ] }
+ , parsed = nopt( types
+ , shorthands
+ , process.argv
+ , 2 )
+
+console.log("parsed", parsed)
+
+if (parsed.help) {
+ console.log("")
+ console.log("nopt cli tester")
+ console.log("")
+ console.log("types")
+ console.log(Object.keys(types).map(function M (t) {
+ var type = types[t]
+ if (Array.isArray(type)) {
+ return [t, type.map(function (type) { return type.name })]
+ }
+ return [t, type && type.name]
+ }).reduce(function (s, i) {
+ s[i[0]] = i[1]
+ return s
+ }, {}))
+ console.log("")
+ console.log("shorthands")
+ console.log(shorthands)
+}
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/bin/nopt.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsnode_modulesnoptexamplesmyprogramjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/examples/my-program.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/examples/my-program.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/examples/my-program.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+#!/usr/bin/env node
+
+//process.env.DEBUG_NOPT = 1
+
+// my-program.js
+var nopt = require("../lib/nopt")
+ , Stream = require("stream").Stream
+ , path = require("path")
+ , knownOpts = { "foo" : [String, null]
+ , "bar" : [Stream, Number]
+ , "baz" : path
+ , "bloo" : [ "big", "medium", "small" ]
+ , "flag" : Boolean
+ , "pick" : Boolean
+ }
+ , shortHands = { "foofoo" : ["--foo", "Mr. Foo"]
+ , "b7" : ["--bar", "7"]
+ , "m" : ["--bloo", "medium"]
+ , "p" : ["--pick"]
+ , "f" : ["--flag", "true"]
+ , "g" : ["--flag"]
+ , "s" : "--flag"
+ }
+ // everything is optional.
+ // knownOpts and shorthands default to {}
+ // arg list defaults to process.argv
+ // slice defaults to 2
+ , parsed = nopt(knownOpts, shortHands, process.argv, 2)
+
+console.log("parsed =\n"+ require("util").inspect(parsed))
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/examples/my-program.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsnode_modulesnoptlibnoptjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/lib/nopt.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/lib/nopt.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/lib/nopt.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,555 @@
</span><ins>+// info about each config option.
+
+var debug = process.env.DEBUG_NOPT || process.env.NOPT_DEBUG
+ ? function () { console.error.apply(console, arguments) }
+ : function () {}
+
+var url = require("url")
+ , path = require("path")
+ , Stream = require("stream").Stream
+ , abbrev = require("abbrev")
+
+module.exports = exports = nopt
+exports.clean = clean
+
+exports.typeDefs =
+ { String : { type: String, validate: validateString }
+ , Boolean : { type: Boolean, validate: validateBoolean }
+ , url : { type: url, validate: validateUrl }
+ , Number : { type: Number, validate: validateNumber }
+ , path : { type: path, validate: validatePath }
+ , Stream : { type: Stream, validate: validateStream }
+ , Date : { type: Date, validate: validateDate }
+ }
+
+function nopt (types, shorthands, args, slice) {
+ args = args || process.argv
+ types = types || {}
+ shorthands = shorthands || {}
+ if (typeof slice !== "number") slice = 2
+
+ debug(types, shorthands, args, slice)
+
+ args = args.slice(slice)
+ var data = {}
+ , key
+ , remain = []
+ , cooked = args
+ , original = args.slice(0)
+
+ parse(args, data, remain, types, shorthands)
+ // now data is full
+ clean(data, types, exports.typeDefs)
+ data.argv = {remain:remain,cooked:cooked,original:original}
+ Object.defineProperty(data.argv, 'toString', { value: function () {
+ return this.original.map(JSON.stringify).join(" ")
+ }, enumerable: false })
+ return data
+}
+
+function clean (data, types, typeDefs) {
+ typeDefs = typeDefs || exports.typeDefs
+ var remove = {}
+ , typeDefault = [false, true, null, String, Number]
+
+ Object.keys(data).forEach(function (k) {
+ if (k === "argv") return
+ var val = data[k]
+ , isArray = Array.isArray(val)
+ , type = types[k]
+ if (!isArray) val = [val]
+ if (!type) type = typeDefault
+ if (type === Array) type = typeDefault.concat(Array)
+ if (!Array.isArray(type)) type = [type]
+
+ debug("val=%j", val)
+ debug("types=", type)
+ val = val.map(function (val) {
+ // if it's an unknown value, then parse false/true/null/numbers/dates
+ if (typeof val === "string") {
+ debug("string %j", val)
+ val = val.trim()
+ if ((val === "null" && ~type.indexOf(null))
+ || (val === "true" &&
+ (~type.indexOf(true) || ~type.indexOf(Boolean)))
+ || (val === "false" &&
+ (~type.indexOf(false) || ~type.indexOf(Boolean)))) {
+ val = JSON.parse(val)
+ debug("jsonable %j", val)
+ } else if (~type.indexOf(Number) && !isNaN(val)) {
+ debug("convert to number", val)
+ val = +val
+ } else if (~type.indexOf(Date) && !isNaN(Date.parse(val))) {
+ debug("convert to date", val)
+ val = new Date(val)
+ }
+ }
+
+ if (!types.hasOwnProperty(k)) {
+ return val
+ }
+
+ // allow `--no-blah` to set 'blah' to null if null is allowed
+ if (val === false && ~type.indexOf(null) &&
+ !(~type.indexOf(false) || ~type.indexOf(Boolean))) {
+ val = null
+ }
+
+ var d = {}
+ d[k] = val
+ debug("prevalidated val", d, val, types[k])
+ if (!validate(d, k, val, types[k], typeDefs)) {
+ if (exports.invalidHandler) {
+ exports.invalidHandler(k, val, types[k], data)
+ } else if (exports.invalidHandler !== false) {
+ debug("invalid: "+k+"="+val, types[k])
+ }
+ return remove
+ }
+ debug("validated val", d, val, types[k])
+ return d[k]
+ }).filter(function (val) { return val !== remove })
+
+ if (!val.length) delete data[k]
+ else if (isArray) {
+ debug(isArray, data[k], val)
+ data[k] = val
+ } else data[k] = val[0]
+
+ debug("k=%s val=%j", k, val, data[k])
+ })
+}
+
+function validateString (data, k, val) {
+ data[k] = String(val)
+}
+
+function validatePath (data, k, val) {
+ data[k] = path.resolve(String(val))
+ return true
+}
+
+function validateNumber (data, k, val) {
+ debug("validate Number %j %j %j", k, val, isNaN(val))
+ if (isNaN(val)) return false
+ data[k] = +val
+}
+
+function validateDate (data, k, val) {
+ debug("validate Date %j %j %j", k, val, Date.parse(val))
+ var s = Date.parse(val)
+ if (isNaN(s)) return false
+ data[k] = new Date(val)
+}
+
+function validateBoolean (data, k, val) {
+ if (val instanceof Boolean) val = val.valueOf()
+ else if (typeof val === "string") {
+ if (!isNaN(val)) val = !!(+val)
+ else if (val === "null" || val === "false") val = false
+ else val = true
+ } else val = !!val
+ data[k] = val
+}
+
+function validateUrl (data, k, val) {
+ val = url.parse(String(val))
+ if (!val.host) return false
+ data[k] = val.href
+}
+
+function validateStream (data, k, val) {
+ if (!(val instanceof Stream)) return false
+ data[k] = val
+}
+
+function validate (data, k, val, type, typeDefs) {
+ // arrays are lists of types.
+ if (Array.isArray(type)) {
+ for (var i = 0, l = type.length; i < l; i ++) {
+ if (type[i] === Array) continue
+ if (validate(data, k, val, type[i], typeDefs)) return true
+ }
+ delete data[k]
+ return false
+ }
+
+ // an array of anything?
+ if (type === Array) return true
+
+ // NaN is poisonous. Means that something is not allowed.
+ if (type !== type) {
+ debug("Poison NaN", k, val, type)
+ delete data[k]
+ return false
+ }
+
+ // explicit list of values
+ if (val === type) {
+ debug("Explicitly allowed %j", val)
+ // if (isArray) (data[k] = data[k] || []).push(val)
+ // else data[k] = val
+ data[k] = val
+ return true
+ }
+
+ // now go through the list of typeDefs, validate against each one.
+ var ok = false
+ , types = Object.keys(typeDefs)
+ for (var i = 0, l = types.length; i < l; i ++) {
+ debug("test type %j %j %j", k, val, types[i])
+ var t = typeDefs[types[i]]
+ if (t && type === t.type) {
+ var d = {}
+ ok = false !== t.validate(d, k, val)
+ val = d[k]
+ if (ok) {
+ // if (isArray) (data[k] = data[k] || []).push(val)
+ // else data[k] = val
+ data[k] = val
+ break
+ }
+ }
+ }
+ debug("OK? %j (%j %j %j)", ok, k, val, types[i])
+
+ if (!ok) delete data[k]
+ return ok
+}
+
+function parse (args, data, remain, types, shorthands) {
+ debug("parse", args, data, remain)
+
+ var key = null
+ , abbrevs = abbrev(Object.keys(types))
+ , shortAbbr = abbrev(Object.keys(shorthands))
+
+ for (var i = 0; i < args.length; i ++) {
+ var arg = args[i]
+ debug("arg", arg)
+
+ if (arg.match(/^-{2,}$/)) {
+ // done with keys.
+ // the rest are args.
+ remain.push.apply(remain, args.slice(i + 1))
+ args[i] = "--"
+ break
+ }
+ var hadEq = false
+ if (arg.charAt(0) === "-") {
+ if (arg.indexOf("=") !== -1) {
+ hadEq = true
+ var v = arg.split("=")
+ arg = v.shift()
+ v = v.join("=")
+ args.splice.apply(args, [i, 1].concat([arg, v]))
+ }
+ // see if it's a shorthand
+ // if so, splice and back up to re-parse it.
+ var shRes = resolveShort(arg, shorthands, shortAbbr, abbrevs)
+ debug("arg=%j shRes=%j", arg, shRes)
+ if (shRes) {
+ debug(arg, shRes)
+ args.splice.apply(args, [i, 1].concat(shRes))
+ if (arg !== shRes[0]) {
+ i --
+ continue
+ }
+ }
+ arg = arg.replace(/^-+/, "")
+ var no = null
+ while (arg.toLowerCase().indexOf("no-") === 0) {
+ no = !no
+ arg = arg.substr(3)
+ }
+
+ if (abbrevs[arg]) arg = abbrevs[arg]
+
+ var isArray = types[arg] === Array ||
+ Array.isArray(types[arg]) && types[arg].indexOf(Array) !== -1
+
+ var val
+ , la = args[i + 1]
+
+ var isBool = typeof no === 'boolean' ||
+ types[arg] === Boolean ||
+ Array.isArray(types[arg]) && types[arg].indexOf(Boolean) !== -1 ||
+ (typeof types[arg] === 'undefined' && !hadEq) ||
+ (la === "false" &&
+ (types[arg] === null ||
+ Array.isArray(types[arg]) && ~types[arg].indexOf(null)))
+
+ if (isBool) {
+ // just set and move along
+ val = !no
+ // however, also support --bool true or --bool false
+ if (la === "true" || la === "false") {
+ val = JSON.parse(la)
+ la = null
+ if (no) val = !val
+ i ++
+ }
+
+ // also support "foo":[Boolean, "bar"] and "--foo bar"
+ if (Array.isArray(types[arg]) && la) {
+ if (~types[arg].indexOf(la)) {
+ // an explicit type
+ val = la
+ i ++
+ } else if ( la === "null" && ~types[arg].indexOf(null) ) {
+ // null allowed
+ val = null
+ i ++
+ } else if ( !la.match(/^-{2,}[^-]/) &&
+ !isNaN(la) &&
+ ~types[arg].indexOf(Number) ) {
+ // number
+ val = +la
+ i ++
+ } else if ( !la.match(/^-[^-]/) && ~types[arg].indexOf(String) ) {
+ // string
+ val = la
+ i ++
+ }
+ }
+
+ if (isArray) (data[arg] = data[arg] || []).push(val)
+ else data[arg] = val
+
+ continue
+ }
+
+ if (la && la.match(/^-{2,}$/)) {
+ la = undefined
+ i --
+ }
+
+ val = la === undefined ? true : la
+ if (isArray) (data[arg] = data[arg] || []).push(val)
+ else data[arg] = val
+
+ i ++
+ continue
+ }
+ remain.push(arg)
+ }
+}
+
+function resolveShort (arg, shorthands, shortAbbr, abbrevs) {
+ // handle single-char shorthands glommed together, like
+ // npm ls -glp, but only if there is one dash, and only if
+ // all of the chars are single-char shorthands, and it's
+ // not a match to some other abbrev.
+ arg = arg.replace(/^-+/, '')
+ if (abbrevs[arg] && !shorthands[arg]) {
+ return null
+ }
+ if (shortAbbr[arg]) {
+ arg = shortAbbr[arg]
+ } else {
+ var singles = shorthands.___singles
+ if (!singles) {
+ singles = Object.keys(shorthands).filter(function (s) {
+ return s.length === 1
+ }).reduce(function (l,r) { l[r] = true ; return l }, {})
+ shorthands.___singles = singles
+ }
+ var chrs = arg.split("").filter(function (c) {
+ return singles[c]
+ })
+ if (chrs.join("") === arg) return chrs.map(function (c) {
+ return shorthands[c]
+ }).reduce(function (l, r) {
+ return l.concat(r)
+ }, [])
+ }
+
+ if (shorthands[arg] && !Array.isArray(shorthands[arg])) {
+ shorthands[arg] = shorthands[arg].split(/\s+/)
+ }
+ return shorthands[arg]
+}
+
+if (module === require.main) {
+var assert = require("assert")
+ , util = require("util")
+
+ , shorthands =
+ { s : ["--loglevel", "silent"]
+ , d : ["--loglevel", "info"]
+ , dd : ["--loglevel", "verbose"]
+ , ddd : ["--loglevel", "silly"]
+ , noreg : ["--no-registry"]
+ , reg : ["--registry"]
+ , "no-reg" : ["--no-registry"]
+ , silent : ["--loglevel", "silent"]
+ , verbose : ["--loglevel", "verbose"]
+ , h : ["--usage"]
+ , H : ["--usage"]
+ , "?" : ["--usage"]
+ , help : ["--usage"]
+ , v : ["--version"]
+ , f : ["--force"]
+ , desc : ["--description"]
+ , "no-desc" : ["--no-description"]
+ , "local" : ["--no-global"]
+ , l : ["--long"]
+ , p : ["--parseable"]
+ , porcelain : ["--parseable"]
+ , g : ["--global"]
+ }
+
+ , types =
+ { aoa: Array
+ , nullstream: [null, Stream]
+ , date: Date
+ , str: String
+ , browser : String
+ , cache : path
+ , color : ["always", Boolean]
+ , depth : Number
+ , description : Boolean
+ , dev : Boolean
+ , editor : path
+ , force : Boolean
+ , global : Boolean
+ , globalconfig : path
+ , group : [String, Number]
+ , gzipbin : String
+ , logfd : [Number, Stream]
+ , loglevel : ["silent","win","error","warn","info","verbose","silly"]
+ , long : Boolean
+ , "node-version" : [false, String]
+ , npaturl : url
+ , npat : Boolean
+ , "onload-script" : [false, String]
+ , outfd : [Number, Stream]
+ , parseable : Boolean
+ , pre: Boolean
+ , prefix: path
+ , proxy : url
+ , "rebuild-bundle" : Boolean
+ , registry : url
+ , searchopts : String
+ , searchexclude: [null, String]
+ , shell : path
+ , t: [Array, String]
+ , tag : String
+ , tar : String
+ , tmp : path
+ , "unsafe-perm" : Boolean
+ , usage : Boolean
+ , user : String
+ , username : String
+ , userconfig : path
+ , version : Boolean
+ , viewer: path
+ , _exit : Boolean
+ }
+
+; [["-v", {version:true}, []]
+ ,["---v", {version:true}, []]
+ ,["ls -s --no-reg connect -d",
+ {loglevel:"info",registry:null},["ls","connect"]]
+ ,["ls ---s foo",{loglevel:"silent"},["ls","foo"]]
+ ,["ls --registry blargle", {}, ["ls"]]
+ ,["--no-registry", {registry:null}, []]
+ ,["--no-color true", {color:false}, []]
+ ,["--no-color false", {color:true}, []]
+ ,["--no-color", {color:false}, []]
+ ,["--color false", {color:false}, []]
+ ,["--color --logfd 7", {logfd:7,color:true}, []]
+ ,["--color=true", {color:true}, []]
+ ,["--logfd=10", {logfd:10}, []]
+ ,["--tmp=/tmp -tar=gtar",{tmp:"/tmp",tar:"gtar"},[]]
+ ,["--tmp=tmp -tar=gtar",
+ {tmp:path.resolve(process.cwd(), "tmp"),tar:"gtar"},[]]
+ ,["--logfd x", {}, []]
+ ,["a -true -- -no-false", {true:true},["a","-no-false"]]
+ ,["a -no-false", {false:false},["a"]]
+ ,["a -no-no-true", {true:true}, ["a"]]
+ ,["a -no-no-no-false", {false:false}, ["a"]]
+ ,["---NO-no-No-no-no-no-nO-no-no"+
+ "-No-no-no-no-no-no-no-no-no"+
+ "-no-no-no-no-NO-NO-no-no-no-no-no-no"+
+ "-no-body-can-do-the-boogaloo-like-I-do"
+ ,{"body-can-do-the-boogaloo-like-I-do":false}, []]
+ ,["we are -no-strangers-to-love "+
+ "--you-know=the-rules --and=so-do-i "+
+ "---im-thinking-of=a-full-commitment "+
+ "--no-you-would-get-this-from-any-other-guy "+
+ "--no-gonna-give-you-up "+
+ "-no-gonna-let-you-down=true "+
+ "--no-no-gonna-run-around false "+
+ "--desert-you=false "+
+ "--make-you-cry false "+
+ "--no-tell-a-lie "+
+ "--no-no-and-hurt-you false"
+ ,{"strangers-to-love":false
+ ,"you-know":"the-rules"
+ ,"and":"so-do-i"
+ ,"you-would-get-this-from-any-other-guy":false
+ ,"gonna-give-you-up":false
+ ,"gonna-let-you-down":false
+ ,"gonna-run-around":false
+ ,"desert-you":false
+ ,"make-you-cry":false
+ ,"tell-a-lie":false
+ ,"and-hurt-you":false
+ },["we", "are"]]
+ ,["-t one -t two -t three"
+ ,{t: ["one", "two", "three"]}
+ ,[]]
+ ,["-t one -t null -t three four five null"
+ ,{t: ["one", "null", "three"]}
+ ,["four", "five", "null"]]
+ ,["-t foo"
+ ,{t:["foo"]}
+ ,[]]
+ ,["--no-t"
+ ,{t:["false"]}
+ ,[]]
+ ,["-no-no-t"
+ ,{t:["true"]}
+ ,[]]
+ ,["-aoa one -aoa null -aoa 100"
+ ,{aoa:["one", null, 100]}
+ ,[]]
+ ,["-str 100"
+ ,{str:"100"}
+ ,[]]
+ ,["--color always"
+ ,{color:"always"}
+ ,[]]
+ ,["--no-nullstream"
+ ,{nullstream:null}
+ ,[]]
+ ,["--nullstream false"
+ ,{nullstream:null}
+ ,[]]
+ ,["--notadate=2011-01-25"
+ ,{notadate: "2011-01-25"}
+ ,[]]
+ ,["--date 2011-01-25"
+ ,{date: new Date("2011-01-25")}
+ ,[]]
+ ].forEach(function (test) {
+ var argv = test[0].split(/\s+/)
+ , opts = test[1]
+ , rem = test[2]
+ , actual = nopt(types, shorthands, argv, 0)
+ , parsed = actual.argv
+ delete actual.argv
+ console.log(util.inspect(actual, false, 2, true), parsed.remain)
+ for (var i in opts) {
+ var e = JSON.stringify(opts[i])
+ , a = JSON.stringify(actual[i] === undefined ? null : actual[i])
+ if (e && typeof e === "object") {
+ assert.deepEqual(e, a)
+ } else {
+ assert.equal(e, a)
+ }
+ }
+ assert.deepEqual(rem, parsed.remain)
+ })
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesnoptnode_modulesabbrevREADMEmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/README.md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/README.md (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/README.md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+# abbrev-js
+
+Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
+
+Usage:
+
+ var abbrev = require("abbrev");
+ abbrev("foo", "fool", "folding", "flop");
+
+ // returns:
+ { fl: 'flop'
+ , flo: 'flop'
+ , flop: 'flop'
+ , fol: 'folding'
+ , fold: 'folding'
+ , foldi: 'folding'
+ , foldin: 'folding'
+ , folding: 'folding'
+ , foo: 'foo'
+ , fool: 'fool'
+ }
+
+This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesnoptnode_modulesabbrevlibabbrevjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/lib/abbrev.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/lib/abbrev.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/lib/abbrev.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,106 @@
</span><ins>+
+module.exports = exports = abbrev.abbrev = abbrev
+
+abbrev.monkeyPatch = monkeyPatch
+
+function monkeyPatch () {
+ Array.prototype.abbrev = function () { return abbrev(this) }
+ Object.prototype.abbrev = function () { return abbrev(Object.keys(this)) }
+}
+
+function abbrev (list) {
+ if (arguments.length !== 1 || !Array.isArray(list)) {
+ list = Array.prototype.slice.call(arguments, 0)
+ }
+ for (var i = 0, l = list.length, args = [] ; i < l ; i ++) {
+ args[i] = typeof list[i] === "string" ? list[i] : String(list[i])
+ }
+
+ // sort them lexicographically, so that they're next to their nearest kin
+ args = args.sort(lexSort)
+
+ // walk through each, seeing how much it has in common with the next and previous
+ var abbrevs = {}
+ , prev = ""
+ for (var i = 0, l = args.length ; i < l ; i ++) {
+ var current = args[i]
+ , next = args[i + 1] || ""
+ , nextMatches = true
+ , prevMatches = true
+ if (current === next) continue
+ for (var j = 0, cl = current.length ; j < cl ; j ++) {
+ var curChar = current.charAt(j)
+ nextMatches = nextMatches && curChar === next.charAt(j)
+ prevMatches = prevMatches && curChar === prev.charAt(j)
+ if (nextMatches || prevMatches) continue
+ else {
+ j ++
+ break
+ }
+ }
+ prev = current
+ if (j === cl) {
+ abbrevs[current] = current
+ continue
+ }
+ for (var a = current.substr(0, j) ; j <= cl ; j ++) {
+ abbrevs[a] = current
+ a += current.charAt(j)
+ }
+ }
+ return abbrevs
+}
+
+function lexSort (a, b) {
+ return a === b ? 0 : a > b ? 1 : -1
+}
+
+
+// tests
+if (module === require.main) {
+
+var assert = require("assert")
+ , sys
+sys = require("util")
+
+console.log("running tests")
+function test (list, expect) {
+ var actual = abbrev(list)
+ assert.deepEqual(actual, expect,
+ "abbrev("+sys.inspect(list)+") === " + sys.inspect(expect) + "\n"+
+ "actual: "+sys.inspect(actual))
+ actual = abbrev.apply(exports, list)
+ assert.deepEqual(abbrev.apply(exports, list), expect,
+ "abbrev("+list.map(JSON.stringify).join(",")+") === " + sys.inspect(expect) + "\n"+
+ "actual: "+sys.inspect(actual))
+}
+
+test([ "ruby", "ruby", "rules", "rules", "rules" ],
+{ rub: 'ruby'
+, ruby: 'ruby'
+, rul: 'rules'
+, rule: 'rules'
+, rules: 'rules'
+})
+test(["fool", "foom", "pool", "pope"],
+{ fool: 'fool'
+, foom: 'foom'
+, poo: 'pool'
+, pool: 'pool'
+, pop: 'pope'
+, pope: 'pope'
+})
+test(["a", "ab", "abc", "abcd", "abcde", "acde"],
+{ a: 'a'
+, ab: 'ab'
+, abc: 'abc'
+, abcd: 'abcd'
+, abcde: 'abcde'
+, ac: 'acde'
+, acd: 'acde'
+, acde: 'acde'
+})
+
+console.log("pass")
+
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesnoptnode_modulesabbrevpackagejson"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/package.json (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/package.json (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/node_modules/abbrev/package.json 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+{
+ "name": "abbrev",
+ "version": "1.0.3",
+ "description": "Like ruby's abbrev module, but in js",
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me"
+ },
+ "main": "./lib/abbrev.js",
+ "scripts": {
+ "test": "node lib/abbrev.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/isaacs/abbrev-js"
+ },
+ "readme": "# abbrev-js\n\nJust like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).\n\nUsage:\n\n var abbrev = require(\"abbrev\");\n abbrev(\"foo\", \"fool\", \"folding\", \"flop\");\n \n // returns:\n { fl: 'flop'\n , flo: 'flop'\n , flop: 'flop'\n , fol: 'folding'\n , fold: 'folding'\n , foldi: 'folding'\n , foldin: 'folding'\n , folding: 'folding'\n , foo: 'foo'\n , fool: 'fool'\n }\n\nThis is handy for command-line scripts, or other cases where you want to be able to accept shorthands.\n",
+ "_id": "abbrev@1.0.3",
+ "_from": "abbrev@1"
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesnoptpackagejson"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/package.json (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/package.json (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/nopt/package.json 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+{
+ "name": "nopt",
+ "version": "2.0.0",
+ "description": "Option parsing for Node, supporting types, shorthands, etc. Used by npm.",
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "main": "lib/nopt.js",
+ "scripts": {
+ "test": "node lib/nopt.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/isaacs/nopt"
+ },
+ "bin": {
+ "nopt": "./bin/nopt.js"
+ },
+ "license": {
+ "type": "MIT",
+ "url": "https://github.com/isaacs/nopt/raw/master/LICENSE"
+ },
+ "dependencies": {
+ "abbrev": "1"
+ },
+ "readme": "If you want to write an option parser, and have it be good, there are\ntwo ways to do it. The Right Way, and the Wrong Way.\n\nThe Wrong Way is to sit down and write an option parser. We've all done\nthat.\n\nThe Right Way is to write some complex configurable program with so many\noptions that you go half-insane just trying to manage them all, and put\nit off with duct-tape solutions until you see exactly to the core of the\nproblem, and finally snap and write an awesome option parser.\n\nIf you want to write an option parser, don't write an option parser.\nWrite a package manager, or a source control system, or a service\nrestarter, or an operating system. You probably won't end up with a\ngood one of those, but if you don't give up, and you are relentless and\ndiligent enough in your procrastination, you may just end up with a very\nnice option parser.\n\n## USAGE\n\n // my-program.js\n var nopt = require(\"nopt\")\n , Stream =
require(\"stream\").Stream\n , path = require(\"path\")\n , knownOpts = { \"foo\" : [String, null]\n , \"bar\" : [Stream, Number]\n , \"baz\" : path\n , \"bloo\" : [ \"big\", \"medium\", \"small\" ]\n , \"flag\" : Boolean\n , \"pick\" : Boolean\n , \"many\" : [String, Array]\n }\n , shortHands = { \"foofoo\" : [\"--foo\", \"Mr. Foo\"]\n , \"b7\" : [\"--bar\", \"7\"]\n , \"m\" : [\"--bloo\", \"medium\"]\n , \"p\" : [\"--pick\"]\n , \"f\" : [\"--flag\"]\n }\n // everything is opti
onal.\n // knownOpts and shorthands default to {}\n // arg list defaults to process.argv\n // slice defaults to 2\n , parsed = nopt(knownOpts, shortHands, process.argv, 2)\n console.log(parsed)\n\nThis would give you support for any of the following:\n\n```bash\n$ node my-program.js --foo \"blerp\" --no-flag\n{ \"foo\" : \"blerp\", \"flag\" : false }\n\n$ node my-program.js ---bar 7 --foo \"Mr. Hand\" --flag\n{ bar: 7, foo: \"Mr. Hand\", flag: true }\n\n$ node my-program.js --foo \"blerp\" -f -----p\n{ foo: \"blerp\", flag: true, pick: true }\n\n$ node my-program.js -fp --foofoo\n{ foo: \"Mr. Foo\", flag: true, pick: true }\n\n$ node my-program.js --foofoo -- -fp # -- stops the flag parsing.\n{ foo: \"Mr. Foo\", argv: { remain: [\"-fp\"] } }\n\n$ node my-program.js --blatzk 1000 -fp # unknown opts are ok.\n{ blatzk: 10
00, flag: true, pick: true }\n\n$ node my-program.js --blatzk true -fp # but they need a value\n{ blatzk: true, flag: true, pick: true }\n\n$ node my-program.js --no-blatzk -fp # unless they start with \"no-\"\n{ blatzk: false, flag: true, pick: true }\n\n$ node my-program.js --baz b/a/z # known paths are resolved.\n{ baz: \"/Users/isaacs/b/a/z\" }\n\n# if Array is one of the types, then it can take many\n# values, and will always be an array. The other types provided\n# specify what types are allowed in the list.\n\n$ node my-program.js --many 1 --many null --many foo\n{ many: [\"1\", \"null\", \"foo\"] }\n\n$ node my-program.js --many foo\n{ many: [\"foo\"] }\n```\n\nRead the tests at the bottom of `lib/nopt.js` for more examples of\nwhat this puppy can do.\n\n## Types\n\nThe following types are supported, and defined on `nopt.typeDefs`\n\n* String: A normal string. No parsing is done.\n* path: A file system path. Gets
resolved against cwd if not absolute.\n* url: A url. If it doesn't parse, it isn't accepted.\n* Number: Must be numeric.\n* Date: Must parse as a date. If it does, and `Date` is one of the options,\n then it will return a Date object, not a string.\n* Boolean: Must be either `true` or `false`. If an option is a boolean,\n then it does not need a value, and its presence will imply `true` as\n the value. To negate boolean flags, do `--no-whatever` or `--whatever\n false`\n* NaN: Means that the option is strictly not allowed. Any value will\n fail.\n* Stream: An object matching the \"Stream\" class in node. Valuable\n for use when validating programmatically. (npm uses this to let you\n supply any WriteStream on the `outfd` and `logfd` config options.)\n* Array: If `Array` is specified as one of the types, then the value\n will be parsed as a list of options. This means that multiple values\n can be specified, and that the value will always be an array.\n\nIf
a type is an array of values not on this list, then those are\nconsidered valid values. For instance, in the example above, the\n`--bloo` option can only be one of `\"big\"`, `\"medium\"`, or `\"small\"`,\nand any other value will be rejected.\n\nWhen parsing unknown fields, `\"true\"`, `\"false\"`, and `\"null\"` will be\ninterpreted as their JavaScript equivalents, and numeric values will be\ninterpreted as a number.\n\nYou can also mix types and values, or multiple types, in a list. For\ninstance `{ blah: [Number, null] }` would allow a value to be set to\neither a Number or null. When types are ordered, this implies a\npreference, and the first type that can be used to properly interpret\nthe value will be used.\n\nTo define a new type, add it to `nopt.typeDefs`. Each item in that\nhash is an object with a `type` member and a `validate` method. The\n`type` member is an object that matches what goes in the type lis
t. The\n`validate` method is a function that gets called with `validate(data,\nkey, val)`. Validate methods should assign `data[key]` to the valid\nvalue of `val` if it can be handled properly, or return boolean\n`false` if it cannot.\n\nYou can also call `nopt.clean(data, types, typeDefs)` to clean up a\nconfig object and remove its invalid properties.\n\n## Error Handling\n\nBy default, nopt outputs a warning to standard error when invalid\noptions are found. You can change this behavior by assigning a method\nto `nopt.invalidHandler`. This method will be called with\nthe offending `nopt.invalidHandler(key, val, types)`.\n\nIf no `nopt.invalidHandler` is assigned, then it will console.error\nits whining. If it is assigned to boolean `false` then the warning is\nsuppressed.\n\n## Abbreviations\n\nYes, they are supported. If you define options like this:\n\n```javascript\n{ \"foolhardyelephants\" : Boolean\n, \"pileofmonkeys\" : Boolean }\n```\n\nThen this
will work:\n\n```bash\nnode program.js --foolhar --pil\nnode program.js --no-f --pileofmon\n# etc.\n```\n\n## Shorthands\n\nShorthands are a hash of shorter option names to a snippet of args that\nthey expand to.\n\nIf multiple one-character shorthands are all combined, and the\ncombination does not unambiguously match any other option or shorthand,\nthen they will be broken up into their constituent parts. For example:\n\n```json\n{ \"s\" : [\"--loglevel\", \"silent\"]\n, \"g\" : \"--global\"\n, \"f\" : \"--force\"\n, \"p\" : \"--parseable\"\n, \"l\" : \"--long\"\n}\n```\n\n```bash\nnpm ls -sgflp\n# just like doing this:\nnpm ls --loglevel silent --global --force --long --parseable\n```\n\n## The Rest of the args\n\nThe config object returned by nopt is given a special member called\n`argv`, which is an object with the following fields:\n\n* `remain`: The remaining args af
ter all the parsing has occurred.\n* `original`: The args as they originally appeared.\n* `cooked`: The args after flags and shorthands are expanded.\n\n## Slicing\n\nNode programs are called with more or less the exact argv as it appears\nin C land, after the v8 and node-specific options have been plucked off.\nAs such, `argv[0]` is always `node` and `argv[1]` is always the\nJavaScript program being run.\n\nThat's usually not very useful to you. So they're sliced off by\ndefault. If you want them, then you can pass in `0` as the last\nargument, or any other number that you'd like to slice off the start of\nthe list.\n",
+ "_id": "nopt@2.0.0",
+ "_from": "nopt"
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljsdocumentupjson"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/.documentup.json (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/.documentup.json (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/.documentup.json 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+{
+ "name": "ShellJS",
+ "twitter": [
+ "arturadib"
+ ]
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstravisyml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/.travis.yml (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/.travis.yml (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/.travis.yml 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+language: node_js
+node_js:
+ - 0.4
+ - 0.6
+ - 0.7 # development version of 0.8, may be unstable
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljsLICENSE"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/LICENSE (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/LICENSE (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/LICENSE 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+Copyright (c) 2012, Artur Adib <aadib@mozilla.com>
+All rights reserved.
+
+You may use this project under the terms of the New BSD license as follows:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Artur Adib nor the
+ names of the contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL ARTUR ADIB BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljsREADMEmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/README.md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/README.md (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/README.md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,421 @@
</span><ins>+# ShellJS - Unix shell commands for Node.js [![Build Status](https://secure.travis-ci.org/arturadib/shelljs.png)](http://travis-ci.org/arturadib/shelljs)
+
+ShellJS is a portable (**Windows included**) implementation of Unix shell commands on top of the Node.js API. You can use it to eliminate your shell script's dependency on Unix while still keeping its familiar and powerful commands. You can also install it globally so you can run it from outside Node projects - say goodbye to those gnarly Bash scripts!
+
+The project is [unit-tested](http://travis-ci.org/arturadib/shelljs) and is being used at Mozilla's [PDF.js](http://github.com/mozilla/pdf.js), [Butter.js](http://github.com/mozilla/butter) and [others](http://search.npmjs.org/#/shelljs).
+
+
+## Installing
+
+Via npm:
+
+```bash
+$ npm install [-g] shelljs
+```
+
+If the global option `-g` is specified, the binary `shjs` will be installed. This makes it possible to
+run ShellJS scripts much like any shell script from the command line, i.e. without requiring a `node_modules` folder:
+
+```bash
+$ shjs my_script
+```
+
+You can also just copy `shell.js` into your project's directory, and `require()` accordingly.
+
+
+## Examples
+
+### JavaScript
+
+```javascript
+require('shelljs/global');
+
+if (!which('git')) {
+ echo('Sorry, this script requires git');
+ exit(1);
+}
+
+// Copy files to release dir
+mkdir('-p', 'out/Release');
+cp('-R', 'stuff/*', 'out/Release');
+
+// Replace macros in each .js file
+cd('lib');
+ls('*.js').forEach(function(file) {
+ sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
+ sed('-i', /.*REMOVE_THIS_LINE.*\n/, '', file);
+ sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat('macro.js'), file);
+});
+cd('..');
+
+// Run external tool synchronously
+if (exec('git commit -am "Auto-commit"').code !== 0) {
+ echo('Error: Git commit failed');
+ exit(1);
+}
+```
+
+### CoffeeScript
+
+```coffeescript
+require 'shelljs/global'
+
+if not which 'git'
+ echo 'Sorry, this script requires git'
+ exit 1
+
+# Copy files to release dir
+mkdir '-p', 'out/Release'
+cp '-R', 'stuff/*', 'out/Release'
+
+# Replace macros in each .js file
+cd 'lib'
+for file in ls '*.js'
+ sed '-i', 'BUILD_VERSION', 'v0.1.2', file
+ sed '-i', /.*REMOVE_THIS_LINE.*\n/, '', file
+ sed '-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat 'macro.js', file
+cd '..'
+
+# Run external tool synchronously
+if (exec 'git commit -am "Auto-commit"').code != 0
+ echo 'Error: Git commit failed'
+ exit 1
+```
+
+## Global vs. Local
+
+The example above uses the convenience script `shelljs/global` to reduce verbosity. If polluting your global namespace is not desirable, simply require `shelljs`.
+
+Example:
+
+```javascript
+var shell = require('shelljs');
+shell.echo('hello world');
+```
+
+## Make tool
+
+A convenience script `shelljs/make` is also provided to mimic the behavior of a Unix Makefile. In this case all shell objects are global, and command line arguments will cause the script to execute only the corresponding function in the global `target` object. To avoid redundant calls, target functions are executed only once per script.
+
+Example (CoffeeScript):
+
+```coffeescript
+require 'shelljs/make'
+
+target.all = ->
+ target.bundle()
+ target.docs()
+
+target.bundle = ->
+ cd __dirname
+ mkdir 'build'
+ cd 'lib'
+ (cat '*.js').to '../build/output.js'
+
+target.docs = ->
+ cd __dirname
+ mkdir 'docs'
+ cd 'lib'
+ for file in ls '*.js'
+ text = grep '//@', file # extract special comments
+ text.replace '//@', '' # remove comment tags
+ text.to 'docs/my_docs.md'
+```
+
+To run the target `all`, call the above script without arguments: `$ node make`. To run the target `docs`: `$ node make docs`, and so on.
+
+
+
+<!--
+
+ DO NOT MODIFY BEYOND THIS POINT - IT'S AUTOMATICALLY GENERATED
+
+-->
+
+
+## Command reference
+
+
+All commands run synchronously, unless otherwise stated.
+
+
+### cd('dir')
+Changes to directory `dir` for the duration of the script
+
+### pwd()
+Returns the current directory.
+
+### ls([options ,] path [,path ...])
+### ls([options ,] path_array)
+Available options:
+
++ `-R`: recursive
++ `-A`: all files (include files beginning with `.`, except for `.` and `..`)
+
+Examples:
+
+```javascript
+ls('projs/*.js');
+ls('-R', '/users/me', '/tmp');
+ls('-R', ['/users/me', '/tmp']); // same as above
+```
+
+Returns array of files in the given path, or in current directory if no path provided.
+
+### find(path [,path ...])
+### find(path_array)
+Examples:
+
+```javascript
+find('src', 'lib');
+find(['src', 'lib']); // same as above
+find('.').filter(function(file) { return file.match(/\.js$/); });
+```
+
+Returns array of all files (however deep) in the given paths.
+
+The main difference from `ls('-R', path)` is that the resulting file names
+include the base directories, e.g. `lib/resources/file1` instead of just `file1`.
+
+### cp([options ,] source [,source ...], dest)
+### cp([options ,] source_array, dest)
+Available options:
+
++ `-f`: force
++ `-r, -R`: recursive
+
+Examples:
+
+```javascript
+cp('file1', 'dir1');
+cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
+cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
+```
+
+Copies files. The wildcard `*` is accepted.
+
+### rm([options ,] file [, file ...])
+### rm([options ,] file_array)
+Available options:
+
++ `-f`: force
++ `-r, -R`: recursive
+
+Examples:
+
+```javascript
+rm('-rf', '/tmp/*');
+rm('some_file.txt', 'another_file.txt');
+rm(['some_file.txt', 'another_file.txt']); // same as above
+```
+
+Removes files. The wildcard `*` is accepted.
+
+### mv(source [, source ...], dest')
+### mv(source_array, dest')
+Available options:
+
++ `f`: force
+
+Examples:
+
+```javascript
+mv('-f', 'file', 'dir/');
+mv('file1', 'file2', 'dir/');
+mv(['file1', 'file2'], 'dir/'); // same as above
+```
+
+Moves files. The wildcard `*` is accepted.
+
+### mkdir([options ,] dir [, dir ...])
+### mkdir([options ,] dir_array)
+Available options:
+
++ `p`: full path (will create intermediate dirs if necessary)
+
+Examples:
+
+```javascript
+mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g');
+mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above
+```
+
+Creates directories.
+
+### test(expression)
+Available expression primaries:
+
++ `'-b', 'path'`: true if path is a block device
++ `'-c', 'path'`: true if path is a character device
++ `'-d', 'path'`: true if path is a directory
++ `'-e', 'path'`: true if path exists
++ `'-f', 'path'`: true if path is a regular file
++ `'-L', 'path'`: true if path is a symboilc link
++ `'-p', 'path'`: true if path is a pipe (FIFO)
++ `'-S', 'path'`: true if path is a socket
+
+Examples:
+
+```javascript
+if (test('-d', path)) { /* do something with dir */ };
+if (!test('-f', path)) continue; // skip if it's a regular file
+```
+
+Evaluates expression using the available primaries and returns corresponding value.
+
+### cat(file [, file ...])
+### cat(file_array)
+
+Examples:
+
+```javascript
+var str = cat('file*.txt');
+var str = cat('file1', 'file2');
+var str = cat(['file1', 'file2']); // same as above
+```
+
+Returns a string containing the given file, or a concatenated string
+containing the files if more than one file is given (a new line character is
+introduced between each file). Wildcard `*` accepted.
+
+### 'string'.to(file)
+
+Examples:
+
+```javascript
+cat('input.txt').to('output.txt');
+```
+
+Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as
+those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_
+
+### sed([options ,] search_regex, replace_str, file)
+Available options:
+
++ `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_
+
+Examples:
+
+```javascript
+sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');
+sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js');
+```
+
+Reads an input string from `file` and performs a JavaScript `replace()` on the input
+using the given search regex and replacement string. Returns the new string after replacement.
+
+### grep([options ,] regex_filter, file [, file ...])
+### grep([options ,] regex_filter, file_array)
+Available options:
+
++ `-v`: Inverse the sense of the regex and print the lines not matching the criteria.
+
+Examples:
+
+```javascript
+grep('-v', 'GLOBAL_VARIABLE', '*.js');
+grep('GLOBAL_VARIABLE', '*.js');
+```
+
+Reads input string from given files and returns a string containing all lines of the
+file that match the given `regex_filter`. Wildcard `*` accepted.
+
+### which(command)
+
+Examples:
+
+```javascript
+var nodeExec = which('node');
+```
+
+Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions.
+Returns string containing the absolute path to the command.
+
+### echo(string [,string ...])
+
+Examples:
+
+```javascript
+echo('hello world');
+var str = echo('hello world');
+```
+
+Prints string to stdout, and returns string with additional utility methods
+like `.to()`.
+
+### exit(code)
+Exits the current process with the given exit code.
+
+### env['VAR_NAME']
+Object containing environment variables (both getter and setter). Shortcut to process.env.
+
+### exec(command [, options] [, callback])
+Available options (all `false` by default):
+
++ `async`: Asynchronous execution. Defaults to true if a callback is provided.
++ `silent`: Do not echo program output to console.
+
+Examples:
+
+```javascript
+var version = exec('node --version', {silent:true}).output;
+
+var child = exec('some_long_running_process', {async:true});
+child.stdout.on('data', function(data) {
+ /* ... do something with data ... */
+});
+
+exec('some_long_running_process', function(code, output) {
+ console.log('Exit code:', code);
+ console.log('Program output:', output);
+});
+```
+
+Executes the given `command` _synchronously_, unless otherwise specified.
+When in synchronous mode returns the object `{ code:..., output:... }`, containing the program's
+`output` (stdout + stderr) and its exit `code`. Otherwise returns the child process object, and
+the `callback` gets the arguments `(code, output)`.
+
+**Note:** For long-lived processes, it's best to run `exec()` asynchronously as
+the current synchronous implementation uses a lot of CPU. This should be getting
+fixed soon.
+
+## Non-Unix commands
+
+
+### tempdir()
+Searches and returns string containing a writeable, platform-dependent temporary directory.
+Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir).
+
+### error()
+Tests if error occurred in the last command. Returns `null` if no error occurred,
+otherwise returns string explaining the error
+
+### silent([state])
+Example:
+
+```javascript
+var silentState = silent();
+silent(true);
+/* ... */
+silent(silentState); // restore old silent state
+```
+
+Suppresses all command output if `state = true`, except for `echo()` calls.
+Returns state if no arguments given.
+
+## Deprecated
+
+
+### exists(path [, path ...])
+### exists(path_array)
+
+_This function is being deprecated. Use `test()` instead._
+
+Returns true if all the given paths exist.
+
+### verbose()
+
+_This function is being deprecated. Use `silent(false) instead.`_
+
+Enables all output (default)
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljsbinshjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/bin/shjs (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/bin/shjs (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/bin/shjs 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+#!/usr/bin/env node
+require('../global');
+
+if (process.argv.length < 3) {
+ console.log('ShellJS: missing argument (script name)');
+ console.log();
+ process.exit(1);
+}
+
+var scriptName = process.argv[2];
+env['NODE_PATH'] = __dirname + '/../..';
+
+if (!scriptName.match(/\.js/) && !scriptName.match(/\.coffee/)) {
+ if (test('-f', scriptName + '.js'))
+ scriptName += '.js';
+ if (test('-f', scriptName + '.coffee'))
+ scriptName += '.coffee';
+}
+
+if (!test('-f', scriptName)) {
+ console.log('ShellJS: script not found ('+scriptName+')');
+ console.log();
+ process.exit(1);
+}
+
+
+if (scriptName.match(/\.coffee$/)) {
+ //
+ // CoffeeScript
+ //
+ if (which('coffee')) {
+ exec('coffee ' + scriptName, { async: true });
+ } else {
+ console.log('ShellJS: CoffeeScript interpreter not found');
+ console.log();
+ process.exit(1);
+ }
+} else {
+ //
+ // JavaScript
+ //
+ exec('node ' + scriptName, { async: true });
+}
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/bin/shjs
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljsglobaljs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/global.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/global.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/global.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+var shell = require('./shell.js');
+for (cmd in shell)
+ global[cmd] = shell[cmd];
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljsmakejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/make.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/make.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/make.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+require('./global');
+
+global.target = {};
+
+// This ensures we only execute the script targets after the entire script has
+// been evaluated
+var args = process.argv.slice(2);
+setTimeout(function() {
+
+ if (args.length === 1 && args[0] === '--help') {
+ console.log('Available targets:');
+ for (t in target)
+ console.log(' ' + t);
+ return;
+ }
+
+ // Wrap targets to prevent duplicate execution
+ for (t in target) {
+ (function(t, oldTarget){
+
+ // Wrap it
+ target[t] = function(force) {
+ if (oldTarget.done && !force)
+ return;
+ oldTarget.done = true;
+ return oldTarget.apply(oldTarget, arguments);
+ }
+
+ })(t, target[t]);
+ }
+
+ // Execute desired targets
+ if (args.length > 0) {
+ args.forEach(function(arg) {
+ if (arg in target)
+ target[arg]();
+ else {
+ console.log('no such target: ' + arg);
+ exit(1);
+ }
+ });
+ } else if ('all' in target) {
+ target.all();
+ }
+
+}, 0);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljspackagejson"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/package.json (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/package.json (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/package.json 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+{
+ "name": "shelljs",
+ "version": "0.0.8",
+ "author": {
+ "name": "Artur Adib",
+ "email": "aadib@mozilla.com"
+ },
+ "description": "Portable Unix shell commands for Node.js",
+ "keywords": [
+ "unix",
+ "shell",
+ "makefile",
+ "make",
+ "jake",
+ "synchronous"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/arturadib/shelljs.git"
+ },
+ "homepage": "http://github.com/arturadib/shelljs",
+ "main": "./shell.js",
+ "scripts": {
+ "test": "node scripts/run-tests"
+ },
+ "bin": {
+ "shjs": "./bin/shjs"
+ },
+ "dependencies": {},
+ "devDependencies": {},
+ "optionalDependencies": {},
+ "engines": {
+ "node": "*"
+ },
+ "readme": "# ShellJS - Unix shell commands for Node.js [![Build Status](https://secure.travis-ci.org/arturadib/shelljs.png)](http://travis-ci.org/arturadib/shelljs)\n\nShellJS is a portable (**Windows included**) implementation of Unix shell commands on top of the Node.js API. You can use it to eliminate your shell script's dependency on Unix while still keeping its familiar and powerful commands. You can also install it globally so you can run it from outside Node projects - say goodbye to those gnarly Bash scripts!\n\nThe project is [unit-tested](http://travis-ci.org/arturadib/shelljs) and is being used at Mozilla's [PDF.js](http://github.com/mozilla/pdf.js), [Butter.js](http://github.com/mozilla/butter) and [others](http://search.npmjs.org/#/shelljs).\n\n\n## Installing\n\nVia npm:\n\n```bash\n$ npm install [-g] shelljs\n```\n\nIf the global option `-g` is specified, the binary `shjs` will be installed. This makes it possible to\nrun ShellJS scripts much like any
shell script from the command line, i.e. without requiring a `node_modules` folder:\n\n```bash\n$ shjs my_script\n```\n\nYou can also just copy `shell.js` into your project's directory, and `require()` accordingly.\n\n\n## Examples\n\n### JavaScript\n\n```javascript\nrequire('shelljs/global');\n\nif (!which('git')) {\n echo('Sorry, this script requires git');\n exit(1);\n}\n\n// Copy files to release dir\nmkdir('-p', 'out/Release');\ncp('-R', 'stuff/*', 'out/Release');\n\n// Replace macros in each .js file\ncd('lib');\nls('*.js').forEach(function(file) {\n sed('-i', 'BUILD_VERSION', 'v0.1.2', file);\n sed('-i', /.*REMOVE_THIS_LINE.*\\n/, '', file);\n sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\\n/, cat('macro.js'), file);\n});\ncd('..');\n\n// Run external tool synchronously\nif (exec('git commit -am \"Auto-commit\"').code !== 0) {\n echo('Error: Git commit failed');\n exit(1);\n}\n```\n\n### CoffeeScript\n\n```coffeescript\nrequire 'shelljs/global'\n\nif not which 'git
'\n echo 'Sorry, this script requires git'\n exit 1\n\n# Copy files to release dir\nmkdir '-p', 'out/Release'\ncp '-R', 'stuff/*', 'out/Release'\n\n# Replace macros in each .js file\ncd 'lib'\nfor file in ls '*.js'\n sed '-i', 'BUILD_VERSION', 'v0.1.2', file\n sed '-i', /.*REMOVE_THIS_LINE.*\\n/, '', file\n sed '-i', /.*REPLACE_LINE_WITH_MACRO.*\\n/, cat 'macro.js', file\ncd '..'\n\n# Run external tool synchronously\nif (exec 'git commit -am \"Auto-commit\"').code != 0\n echo 'Error: Git commit failed'\n exit 1\n```\n\n## Global vs. Local\n\nThe example above uses the convenience script `shelljs/global` to reduce verbosity. If polluting your global namespace is not desirable, simply require `shelljs`.\n\nExample:\n\n```javascript\nvar shell = require('shelljs');\nshell.echo('hello world');\n```\n\n## Make tool\n\nA convenience script `shelljs/make` is also provided to mimic the behavior of a Unix Makefile. In this case all shell objects are global, and command line
arguments will cause the script to execute only the corresponding function in the global `target` object. To avoid redundant calls, target functions are executed only once per script.\n\nExample (CoffeeScript):\n\n```coffeescript\nrequire 'shelljs/make'\n\ntarget.all = ->\n target.bundle()\n target.docs()\n\ntarget.bundle = ->\n cd __dirname\n mkdir 'build'\n cd 'lib'\n (cat '*.js').to '../build/output.js'\n\ntarget.docs = ->\n cd __dirname\n mkdir 'docs'\n cd 'lib'\n for file in ls '*.js'\n text = grep '//@', file # extract special comments\n text.replace '//@', '' # remove comment tags\n text.to 'docs/my_docs.md'\n```\n\nTo run the target `all`, call the above script without arguments: `$ node make`. To run the target `docs`: `$ node make docs`, and so on.\n\n\n\n<!-- \n\n DO NOT MODIFY BEYOND THIS POINT - IT'S AUTOMATICALLY GENERATED\n\n-->\n\n\n## Command reference\n\n\nAll commands run synchronously, unless otherwise stated.\n\n\n###
cd('dir')\nChanges to directory `dir` for the duration of the script\n\n### pwd()\nReturns the current directory.\n\n### ls([options ,] path [,path ...])\n### ls([options ,] path_array)\nAvailable options:\n\n+ `-R`: recursive\n+ `-A`: all files (include files beginning with `.`, except for `.` and `..`)\n\nExamples:\n\n```javascript\nls('projs/*.js');\nls('-R', '/users/me', '/tmp');\nls('-R', ['/users/me', '/tmp']); // same as above\n```\n\nReturns array of files in the given path, or in current directory if no path provided.\n\n### find(path [,path ...])\n### find(path_array)\nExamples:\n\n```javascript\nfind('src', 'lib');\nfind(['src', 'lib']); // same as above\nfind('.').filter(function(file) { return file.match(/\\.js$/); });\n```\n\nReturns array of all files (however deep) in the given paths.\n\nThe main difference from `ls('-R', path)` is that the resulting file names \ninclude the base directories, e.g. `lib/resources/file1` instead of just `file1`.\n\n### cp([options ,] s
ource [,source ...], dest)\n### cp([options ,] source_array, dest)\nAvailable options:\n\n+ `-f`: force\n+ `-r, -R`: recursive\n\nExamples:\n\n```javascript\ncp('file1', 'dir1');\ncp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');\ncp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above\n```\n\nCopies files. The wildcard `*` is accepted.\n\n### rm([options ,] file [, file ...])\n### rm([options ,] file_array)\nAvailable options:\n\n+ `-f`: force\n+ `-r, -R`: recursive\n\nExamples:\n\n```javascript\nrm('-rf', '/tmp/*');\nrm('some_file.txt', 'another_file.txt');\nrm(['some_file.txt', 'another_file.txt']); // same as above\n```\n\nRemoves files. The wildcard `*` is accepted. \n\n### mv(source [, source ...], dest')\n### mv(source_array, dest')\nAvailable options:\n\n+ `f`: force\n\nExamples:\n\n```javascript\nmv('-f', 'file', 'dir/');\nmv('file1', 'file2', 'dir/');\nmv(['file1', 'file2'], 'dir/'); // same as above\n```\n\nMoves files. The wildcard `*` is accepted.\n\n### mk
dir([options ,] dir [, dir ...])\n### mkdir([options ,] dir_array)\nAvailable options:\n\n+ `p`: full path (will create intermediate dirs if necessary)\n\nExamples:\n\n```javascript\nmkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g');\nmkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above\n```\n\nCreates directories.\n\n### test(expression)\nAvailable expression primaries:\n\n+ `'-b', 'path'`: true if path is a block device\n+ `'-c', 'path'`: true if path is a character device\n+ `'-d', 'path'`: true if path is a directory\n+ `'-e', 'path'`: true if path exists\n+ `'-f', 'path'`: true if path is a regular file\n+ `'-L', 'path'`: true if path is a symboilc link\n+ `'-p', 'path'`: true if path is a pipe (FIFO)\n+ `'-S', 'path'`: true if path is a socket\n\nExamples:\n\n```javascript\nif (test('-d', path)) { /* do something with dir */ };\nif (!test('-f', path)) continue; // skip if it's a regular file\n```\n\nEvaluates expression using the available primaries and returns corresponding
value.\n\n### cat(file [, file ...])\n### cat(file_array)\n\nExamples:\n\n```javascript\nvar str = cat('file*.txt');\nvar str = cat('file1', 'file2');\nvar str = cat(['file1', 'file2']); // same as above\n```\n\nReturns a string containing the given file, or a concatenated string\ncontaining the files if more than one file is given (a new line character is\nintroduced between each file). Wildcard `*` accepted.\n\n### 'string'.to(file)\n\nExamples:\n\n```javascript\ncat('input.txt').to('output.txt');\n```\n\nAnalogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as\nthose returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_\n\n### sed([options ,] search_regex, replace_str, file)\nAvailable options:\n\n+ `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_\n\nExamples:\n\n```javascript\nsed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');\nsed(/.*DELETE_THIS_LINE.*\\n/,
'', 'source.js');\n```\n\nReads an input string from `file` and performs a JavaScript `replace()` on the input\nusing the given search regex and replacement string. Returns the new string after replacement.\n\n### grep([options ,] regex_filter, file [, file ...])\n### grep([options ,] regex_filter, file_array)\nAvailable options:\n\n+ `-v`: Inverse the sense of the regex and print the lines not matching the criteria.\n\nExamples:\n\n```javascript\ngrep('-v', 'GLOBAL_VARIABLE', '*.js');\ngrep('GLOBAL_VARIABLE', '*.js');\n```\n\nReads input string from given files and returns a string containing all lines of the \nfile that match the given `regex_filter`. Wildcard `*` accepted.\n\n### which(command)\n\nExamples:\n\n```javascript\nvar nodeExec = which('node');\n```\n\nSearches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions.\nReturns string containing the absolute path to the command.\n\n### echo(string [,string ...])\n\nExamples:\n\n```ja
vascript\necho('hello world');\nvar str = echo('hello world');\n```\n\nPrints string to stdout, and returns string with additional utility methods\nlike `.to()`.\n\n### exit(code)\nExits the current process with the given exit code.\n\n### env['VAR_NAME']\nObject containing environment variables (both getter and setter). Shortcut to process.env.\n\n### exec(command [, options] [, callback])\nAvailable options (all `false` by default):\n\n+ `async`: Asynchronous execution. Defaults to true if a callback is provided.\n+ `silent`: Do not echo program output to console.\n\nExamples:\n\n```javascript\nvar version = exec('node --version', {silent:true}).output;\n\nvar child = exec('some_long_running_process', {async:true});\nchild.stdout.on('data', function(data) { \n /* ... do something with data ... */ \n});\n\nexec('some_long_running_process', function(code, output) {\n console.log('Exit code:', code);\n console.log('Program output:', output);\n});\n```\n\nExecutes the given `comman
d` _synchronously_, unless otherwise specified. \nWhen in synchronous mode returns the object `{ code:..., output:... }`, containing the program's \n`output` (stdout + stderr) and its exit `code`. Otherwise returns the child process object, and\nthe `callback` gets the arguments `(code, output)`.\n\n**Note:** For long-lived processes, it's best to run `exec()` asynchronously as\nthe current synchronous implementation uses a lot of CPU. This should be getting\nfixed soon.\n\n## Non-Unix commands\n\n\n### tempdir()\nSearches and returns string containing a writeable, platform-dependent temporary directory.\nFollows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir).\n\n### error()\nTests if error occurred in the last command. Returns `null` if no error occurred,\notherwise returns string explaining the error\n\n### silent([state])\nExample:\n\n```javascript\nvar silentState = silent();\nsilent(true);\n/* ... */\nsilent(silentState); // restor
e old silent state\n```\n\nSuppresses all command output if `state = true`, except for `echo()` calls. \nReturns state if no arguments given.\n\n## Deprecated\n\n\n### exists(path [, path ...])\n### exists(path_array)\n\n_This function is being deprecated. Use `test()` instead._\n\nReturns true if all the given paths exist.\n\n### verbose()\n\n_This function is being deprecated. Use `silent(false) instead.`_\n\nEnables all output (default)\n",
+ "readmeFilename": "README.md",
+ "_id": "shelljs@0.0.8",
+ "_from": "shelljs"
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljsscriptsdocsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/scripts/docs.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/scripts/docs.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/scripts/docs.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+#!/usr/bin/env node
+require('../global');
+
+echo('Appending docs to README.md');
+
+cd(__dirname + '/..');
+
+// Extract docs from shell.js
+var docs = grep('//@', 'shell.js');
+// Remove '//@'
+docs = docs.replace(/\/\/\@ ?/g, '');
+// Append docs to README
+sed('-i', /## Command reference(.|\n)*/, '## Command reference\n\n' + docs, 'README.md');
+
+echo('All done.');
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/scripts/docs.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljsscriptsruntestsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/scripts/run-tests.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/scripts/run-tests.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/scripts/run-tests.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+#!/usr/bin/env node
+require('../global');
+
+var failed = false;
+
+cd(__dirname + '/../test');
+ls('*.js').forEach(function(file) {
+ echo('Running test:', file);
+ if (exec('node '+file).code !== 123) { // 123 avoids false positives (e.g. premature exit)
+ failed = true;
+ echo('*** FAILED! (missing return code)');
+ }
+});
+
+if (failed) {
+ echo();
+ echo('WARNING: Some tests did not pass!');
+ exit(1);
+} else {
+ echo();
+ echo('All tests passed.');
+}
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/scripts/run-tests.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljsshelljs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/shell.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/shell.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/shell.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,1513 @@
</span><ins>+//
+// ShellJS
+// Unix shell commands on top of Node's API
+//
+// Copyright (c) 2012 Artur Adib
+// http://github.com/arturadib/shelljs
+//
+
+var fs = require('fs'),
+ path = require('path'),
+ util = require('util'),
+ vm = require('vm'),
+ child = require('child_process'),
+ os = require('os');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+var state = {
+ error: null,
+ fatal: false,
+ silent: false,
+ currentCmd: 'shell.js',
+ tempDir: null
+ },
+ platform = os.type().match(/^Win/) ? 'win' : 'unix';
+
+
+//@
+//@ All commands run synchronously, unless otherwise stated.
+//@
+
+
+//@
+//@ ### cd('dir')
+//@ Changes to directory `dir` for the duration of the script
+function _cd(options, dir) {
+ if (!dir)
+ error('directory not specified');
+
+ if (!fs.existsSync(dir))
+ error('no such file or directory: ' + dir);
+
+ if (fs.existsSync(dir) && !fs.statSync(dir).isDirectory())
+ error('not a directory: ' + dir);
+
+ process.chdir(dir);
+};
+exports.cd = wrap('cd', _cd);
+
+//@
+//@ ### pwd()
+//@ Returns the current directory.
+function _pwd(options) {
+ var pwd = path.resolve(process.cwd());
+ return ShellString(pwd);
+};
+exports.pwd = wrap('pwd', _pwd);
+
+
+//@
+//@ ### ls([options ,] path [,path ...])
+//@ ### ls([options ,] path_array)
+//@ Available options:
+//@
+//@ + `-R`: recursive
+//@ + `-A`: all files (include files beginning with `.`, except for `.` and `..`)
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ ls('projs/*.js');
+//@ ls('-R', '/users/me', '/tmp');
+//@ ls('-R', ['/users/me', '/tmp']); // same as above
+//@ ```
+//@
+//@ Returns array of files in the given path, or in current directory if no path provided.
+function _ls(options, paths) {
+ options = parseOptions(options, {
+ 'R': 'recursive',
+ 'A': 'all',
+ 'a': 'all_deprecated'
+ });
+
+ if (options.all_deprecated) {
+ // We won't support the -a option as it's hard to image why it's useful
+ // (it includes '.' and '..' in addition to '.*' files)
+ // For backwards compatibility we'll dump a deprecated message and proceed as before
+ log('ls: Option -a is deprecated. Use -A instead');
+ options.all = true;
+ }
+
+ if (!paths)
+ paths = ['.'];
+ else if (typeof paths === 'object')
+ paths = paths; // assume array
+ else if (typeof paths === 'string')
+ paths = [].slice.call(arguments, 1);
+
+ var list = [];
+
+ // Conditionally pushes file to list - returns true if pushed, false otherwise
+ // (e.g. prevents hidden files to be included unless explicitly told so)
+ function pushFile(file, query) {
+ // hidden file?
+ if (path.basename(file)[0] === '.') {
+ // not explicitly asking for hidden files?
+ if (!options.all && !(path.basename(query)[0] === '.' && path.basename(query).length > 1))
+ return false;
+ }
+
+ if (platform === 'win')
+ file = file.replace(/\\/g, '/');
+
+ list.push(file);
+ return true;
+ }
+
+ paths.forEach(function(p) {
+ if (fs.existsSync(p)) {
+ // Simple file?
+ if (fs.statSync(p).isFile()) {
+ pushFile(p, p);
+ return; // continue
+ }
+
+ // Simple dir?
+ if (fs.statSync(p).isDirectory()) {
+ // Iterate over p contents
+ fs.readdirSync(p).forEach(function(file) {
+ if (!pushFile(file, p))
+ return;
+
+ // Recursive?
+ if (options.recursive) {
+ var oldDir = _pwd();
+ _cd('', p);
+ if (fs.statSync(file).isDirectory())
+ list = list.concat(_ls('-R'+(options.all?'A':''), file+'/*'));
+ _cd('', oldDir);
+ }
+ });
+ return; // continue
+ }
+ }
+
+ // p does not exist - possible wildcard present
+
+ var basename = path.basename(p);
+ var dirname = path.dirname(p);
+ // Wildcard present on an existing dir? (e.g. '/tmp/*.js')
+ if (basename.search(/\*/) > -1 && fs.existsSync(dirname) && fs.statSync(dirname).isDirectory) {
+ // Escape special regular expression chars
+ var regexp = basename.replace(/(\^|\$|\(|\)|\<|\>|\[|\]|\{|\}|\.|\+|\?)/g, '\\$1');
+ // Translates wildcard into regex
+ regexp = '^' + regexp.replace(/\*/g, '.*') + '$';
+ // Iterate over directory contents
+ fs.readdirSync(dirname).forEach(function(file) {
+ if (file.match(new RegExp(regexp))) {
+ if (!pushFile(path.normalize(dirname+'/'+file), basename))
+ return;
+
+ // Recursive?
+ if (options.recursive) {
+ var pp = dirname + '/' + file;
+ if (fs.statSync(pp).isDirectory())
+ list = list.concat(_ls('-R'+(options.all?'A':''), pp+'/*'));
+ } // recursive
+ } // if file matches
+ }); // forEach
+ return;
+ }
+
+ error('no such file or directory: ' + p, true);
+ });
+
+ return list;
+};
+exports.ls = wrap('ls', _ls);
+
+
+//@
+//@ ### find(path [,path ...])
+//@ ### find(path_array)
+//@ Examples:
+//@
+//@ ```javascript
+//@ find('src', 'lib');
+//@ find(['src', 'lib']); // same as above
+//@ find('.').filter(function(file) { return file.match(/\.js$/); });
+//@ ```
+//@
+//@ Returns array of all files (however deep) in the given paths.
+//@
+//@ The main difference from `ls('-R', path)` is that the resulting file names
+//@ include the base directories, e.g. `lib/resources/file1` instead of just `file1`.
+function _find(options, paths) {
+ if (!paths)
+ error('no path specified');
+ else if (typeof paths === 'object')
+ paths = paths; // assume array
+ else if (typeof paths === 'string')
+ paths = [].slice.call(arguments, 1);
+
+ var list = [];
+
+ function pushFile(file) {
+ if (platform === 'win')
+ file = file.replace(/\\/g, '/');
+ list.push(file);
+ }
+
+ // why not simply do ls('-R', paths)? because the output wouldn't give the base dirs
+ // to get the base dir in the output, we need instead ls('-R', 'dir/*') for every directory
+
+ paths.forEach(function(file) {
+ pushFile(file);
+
+ if (fs.statSync(file).isDirectory()) {
+ _ls('-RA', file+'/*').forEach(function(subfile) {
+ pushFile(subfile);
+ });
+ }
+ });
+
+ return list;
+}
+exports.find = wrap('find', _find);
+
+
+//@
+//@ ### cp([options ,] source [,source ...], dest)
+//@ ### cp([options ,] source_array, dest)
+//@ Available options:
+//@
+//@ + `-f`: force
+//@ + `-r, -R`: recursive
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ cp('file1', 'dir1');
+//@ cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
+//@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
+//@ ```
+//@
+//@ Copies files. The wildcard `*` is accepted.
+function _cp(options, sources, dest) {
+ options = parseOptions(options, {
+ 'f': 'force',
+ 'R': 'recursive',
+ 'r': 'recursive'
+ });
+
+ // Get sources, dest
+ if (arguments.length < 3) {
+ error('missing <source> and/or <dest>');
+ } else if (arguments.length > 3) {
+ sources = [].slice.call(arguments, 1, arguments.length - 1);
+ dest = arguments[arguments.length - 1];
+ } else if (typeof sources === 'string') {
+ sources = [sources];
+ } else if ('length' in sources) {
+ sources = sources; // no-op for array
+ } else {
+ error('invalid arguments');
+ }
+
+ // Dest is not existing dir, but multiple sources given
+ if ((!fs.existsSync(dest) || !fs.statSync(dest).isDirectory()) && sources.length > 1)
+ error('dest is not a directory (too many sources)');
+
+ // Dest is an existing file, but no -f given
+ if (fs.existsSync(dest) && fs.statSync(dest).isFile() && !options.force)
+ error('dest file already exists: ' + dest);
+
+ // Recursive allows the shortcut syntax "sourcedir/" for "sourcedir/*"
+ // (see Github issue #15)
+ if (options.recursive) {
+ sources.forEach(function(src, i) {
+ if (src[src.length - 1] === '/')
+ sources[i] += '*';
+ });
+ }
+
+ sources = expand(sources);
+
+ sources.forEach(function(src) {
+ if (!fs.existsSync(src)) {
+ error('no such file or directory: '+src, true);
+ return; // skip file
+ }
+
+ // If here, src exists
+
+ if (fs.statSync(src).isDirectory()) {
+ if (!options.recursive) {
+ // Non-Recursive
+ log(src + ' is a directory (not copied)');
+ } else {
+ // Recursive
+ // 'cp /a/source dest' should create 'source' in 'dest'
+ var newDest = dest+'/'+path.basename(src),
+ checkDir = fs.statSync(src);
+ try {
+ fs.mkdirSync(newDest, checkDir.mode);
+ } catch (e) {
+ //if the directory already exists, that's okay
+ if (e.code !== 'EEXIST') throw e;
+ }
+ cpdirSyncRecursive(src, newDest, {force: options.force});
+ }
+ return; // done with dir
+ }
+
+ // If here, src is a file
+
+ // When copying to '/path/dir':
+ // thisDest = '/path/dir/file1'
+ var thisDest = dest;
+ if (fs.existsSync(dest) && fs.statSync(dest).isDirectory())
+ thisDest = path.normalize(dest + '/' + path.basename(src));
+
+ if (fs.existsSync(thisDest) && !options.force) {
+ error('dest file already exists: ' + thisDest, true);
+ return; // skip file
+ }
+
+ copyFileSync(src, thisDest);
+ }); // forEach(src)
+}; // cp
+exports.cp = wrap('cp', _cp);
+
+//@
+//@ ### rm([options ,] file [, file ...])
+//@ ### rm([options ,] file_array)
+//@ Available options:
+//@
+//@ + `-f`: force
+//@ + `-r, -R`: recursive
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ rm('-rf', '/tmp/*');
+//@ rm('some_file.txt', 'another_file.txt');
+//@ rm(['some_file.txt', 'another_file.txt']); // same as above
+//@ ```
+//@
+//@ Removes files. The wildcard `*` is accepted.
+function _rm(options, files) {
+ options = parseOptions(options, {
+ 'f': 'force',
+ 'r': 'recursive',
+ 'R': 'recursive'
+ });
+ if (!files)
+ error('no paths given');
+
+ if (typeof files === 'string')
+ files = [].slice.call(arguments, 1);
+ // if it's array leave it as it is
+
+ files = expand(files);
+
+ files.forEach(function(file) {
+ if (!fs.existsSync(file)) {
+ // Path does not exist, no force flag given
+ if (!options.force)
+ error('no such file or directory: '+file, true);
+
+ return; // skip file
+ }
+
+ // If here, path exists
+
+ // Remove simple file
+ if (fs.statSync(file).isFile()) {
+
+ // Do not check for file writing permissions
+ if (options.force) {
+ _unlinkSync(file);
+ return;
+ }
+
+ if (isWriteable(file))
+ _unlinkSync(file);
+ else
+ error('permission denied: '+file, true);
+
+ return;
+ } // simple file
+
+ // Path is an existing directory, but no -r flag given
+ if (fs.statSync(file).isDirectory() && !options.recursive) {
+ error('path is a directory', true);
+ return; // skip path
+ }
+
+ // Recursively remove existing directory
+ if (fs.statSync(file).isDirectory() && options.recursive) {
+ rmdirSyncRecursive(file, options.force);
+ }
+ }); // forEach(file)
+}; // rm
+exports.rm = wrap('rm', _rm);
+
+//@
+//@ ### mv(source [, source ...], dest')
+//@ ### mv(source_array, dest')
+//@ Available options:
+//@
+//@ + `f`: force
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ mv('-f', 'file', 'dir/');
+//@ mv('file1', 'file2', 'dir/');
+//@ mv(['file1', 'file2'], 'dir/'); // same as above
+//@ ```
+//@
+//@ Moves files. The wildcard `*` is accepted.
+function _mv(options, sources, dest) {
+ options = parseOptions(options, {
+ 'f': 'force'
+ });
+
+ // Get sources, dest
+ if (arguments.length < 3) {
+ error('missing <source> and/or <dest>');
+ } else if (arguments.length > 3) {
+ sources = [].slice.call(arguments, 1, arguments.length - 1);
+ dest = arguments[arguments.length - 1];
+ } else if (typeof sources === 'string') {
+ sources = [sources];
+ } else if ('length' in sources) {
+ sources = sources; // no-op for array
+ } else {
+ error('invalid arguments');
+ }
+
+ sources = expand(sources);
+
+ // Dest is not existing dir, but multiple sources given
+ if ((!fs.existsSync(dest) || !fs.statSync(dest).isDirectory()) && sources.length > 1)
+ error('dest is not a directory (too many sources)');
+
+ // Dest is an existing file, but no -f given
+ if (fs.existsSync(dest) && fs.statSync(dest).isFile() && !options.force)
+ error('dest file already exists: ' + dest);
+
+ sources.forEach(function(src) {
+ if (!fs.existsSync(src)) {
+ error('no such file or directory: '+src, true);
+ return; // skip file
+ }
+
+ // If here, src exists
+
+ // When copying to '/path/dir':
+ // thisDest = '/path/dir/file1'
+ var thisDest = dest;
+ if (fs.existsSync(dest) && fs.statSync(dest).isDirectory())
+ thisDest = path.normalize(dest + '/' + path.basename(src));
+
+ if (fs.existsSync(thisDest) && !options.force) {
+ error('dest file already exists: ' + thisDest, true);
+ return; // skip file
+ }
+
+ if (path.resolve(src) === path.dirname(path.resolve(thisDest))) {
+ error('cannot move to self: '+src, true);
+ return; // skip file
+ }
+
+ fs.renameSync(src, thisDest);
+ }); // forEach(src)
+}; // mv
+exports.mv = wrap('mv', _mv);
+
+//@
+//@ ### mkdir([options ,] dir [, dir ...])
+//@ ### mkdir([options ,] dir_array)
+//@ Available options:
+//@
+//@ + `p`: full path (will create intermediate dirs if necessary)
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g');
+//@ mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above
+//@ ```
+//@
+//@ Creates directories.
+function _mkdir(options, dirs) {
+ options = parseOptions(options, {
+ 'p': 'fullpath'
+ });
+ if (!dirs)
+ error('no paths given');
+
+ if (typeof dirs === 'string')
+ dirs = [].slice.call(arguments, 1);
+ // if it's array leave it as it is
+
+ dirs.forEach(function(dir) {
+ if (fs.existsSync(dir)) {
+ if (!options.fullpath)
+ error('path already exists: ' + dir, true);
+ return; // skip dir
+ }
+
+ // Base dir does not exist, and no -p option given
+ var baseDir = path.dirname(dir);
+ if (!fs.existsSync(baseDir) && !options.fullpath) {
+ error('no such file or directory: ' + baseDir, true);
+ return; // skip dir
+ }
+
+ if (options.fullpath)
+ mkdirSyncRecursive(dir);
+ else
+ fs.mkdirSync(dir, 0777);
+ });
+}; // mkdir
+exports.mkdir = wrap('mkdir', _mkdir);
+
+//@
+//@ ### test(expression)
+//@ Available expression primaries:
+//@
+//@ + `'-b', 'path'`: true if path is a block device
+//@ + `'-c', 'path'`: true if path is a character device
+//@ + `'-d', 'path'`: true if path is a directory
+//@ + `'-e', 'path'`: true if path exists
+//@ + `'-f', 'path'`: true if path is a regular file
+//@ + `'-L', 'path'`: true if path is a symboilc link
+//@ + `'-p', 'path'`: true if path is a pipe (FIFO)
+//@ + `'-S', 'path'`: true if path is a socket
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ if (test('-d', path)) { /* do something with dir */ };
+//@ if (!test('-f', path)) continue; // skip if it's a regular file
+//@ ```
+//@
+//@ Evaluates expression using the available primaries and returns corresponding value.
+function _test(options, path) {
+ if (!path)
+ error('no path given');
+
+ // hack - only works with unary primaries
+ options = parseOptions(options, {
+ 'b': 'block',
+ 'c': 'character',
+ 'd': 'directory',
+ 'e': 'exists',
+ 'f': 'file',
+ 'L': 'link',
+ 'p': 'pipe',
+ 'S': 'socket'
+ });
+
+ var canInterpret = false;
+ for (var key in options)
+ if (options[key] === true) {
+ canInterpret = true;
+ break;
+ }
+
+ if (!canInterpret)
+ error('could not interpret expression');
+
+ if (!fs.existsSync(path))
+ return false;
+
+ if (options.exists)
+ return true;
+
+ if (options.link)
+ return fs.lstatSync(path).isSymbolicLink();
+
+ var stats = fs.statSync(path);
+
+ if (options.block)
+ return stats.isBlockDevice();
+
+ if (options.character)
+ return stats.isCharacterDevice();
+
+ if (options.directory)
+ return stats.isDirectory();
+
+ if (options.file)
+ return stats.isFile();
+
+ if (options.pipe)
+ return stats.isFIFO();
+
+ if (options.socket)
+ return stats.isSocket()
+}; // test
+exports.test = wrap('test', _test);
+
+
+//@
+//@ ### cat(file [, file ...])
+//@ ### cat(file_array)
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ var str = cat('file*.txt');
+//@ var str = cat('file1', 'file2');
+//@ var str = cat(['file1', 'file2']); // same as above
+//@ ```
+//@
+//@ Returns a string containing the given file, or a concatenated string
+//@ containing the files if more than one file is given (a new line character is
+//@ introduced between each file). Wildcard `*` accepted.
+function _cat(options, files) {
+ var cat = '';
+
+ if (!files)
+ error('no paths given');
+
+ if (typeof files === 'string')
+ files = [].slice.call(arguments, 1);
+ // if it's array leave it as it is
+
+ files = expand(files);
+
+ files.forEach(function(file) {
+ if (!fs.existsSync(file))
+ error('no such file or directory: ' + file);
+
+ cat += fs.readFileSync(file, 'utf8') + '\n';
+ });
+
+ if (cat[cat.length-1] === '\n')
+ cat = cat.substring(0, cat.length-1);
+
+ return ShellString(cat);
+};
+exports.cat = wrap('cat', _cat);
+
+//@
+//@ ### 'string'.to(file)
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ cat('input.txt').to('output.txt');
+//@ ```
+//@
+//@ Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as
+//@ those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_
+function _to(options, file) {
+ if (!file)
+ error('wrong arguments');
+
+ if (!fs.existsSync( path.dirname(file) ))
+ error('no such file or directory: ' + path.dirname(file));
+
+ try {
+ fs.writeFileSync(file, this.toString(), 'utf8');
+ } catch(e) {
+ error('could not write to file (code '+e.code+'): '+file, true);
+ }
+};
+// In the future, when Proxies are default, we can add methods like `.to()` to primitive strings.
+// For now, this is a dummy function to bookmark places we need such strings
+function ShellString(str) {
+ return str;
+}
+String.prototype.to = wrap('to', _to);
+
+//@
+//@ ### sed([options ,] search_regex, replace_str, file)
+//@ Available options:
+//@
+//@ + `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');
+//@ sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js');
+//@ ```
+//@
+//@ Reads an input string from `file` and performs a JavaScript `replace()` on the input
+//@ using the given search regex and replacement string. Returns the new string after replacement.
+function _sed(options, regex, replacement, file) {
+ options = parseOptions(options, {
+ 'i': 'inplace'
+ });
+
+ if (typeof replacement === 'string')
+ replacement = replacement; // no-op
+ else if (typeof replacement === 'number')
+ replacement = replacement.toString(); // fallback
+ else
+ error('invalid replacement string');
+
+ if (!file)
+ error('no file given');
+
+ if (!fs.existsSync(file))
+ error('no such file or directory: ' + file);
+
+ var result = fs.readFileSync(file, 'utf8').replace(regex, replacement);
+ if (options.inplace)
+ fs.writeFileSync(file, result, 'utf8');
+
+ return ShellString(result);
+};
+exports.sed = wrap('sed', _sed);
+
+//@
+//@ ### grep([options ,] regex_filter, file [, file ...])
+//@ ### grep([options ,] regex_filter, file_array)
+//@ Available options:
+//@
+//@ + `-v`: Inverse the sense of the regex and print the lines not matching the criteria.
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ grep('-v', 'GLOBAL_VARIABLE', '*.js');
+//@ grep('GLOBAL_VARIABLE', '*.js');
+//@ ```
+//@
+//@ Reads input string from given files and returns a string containing all lines of the
+//@ file that match the given `regex_filter`. Wildcard `*` accepted.
+function _grep(options, regex, files) {
+ options = parseOptions(options, {
+ 'v': 'inverse'
+ });
+
+ if (!files)
+ error('no paths given');
+
+ if (typeof files === 'string')
+ files = [].slice.call(arguments, 2);
+ // if it's array leave it as it is
+
+ files = expand(files);
+
+ var grep = '';
+ files.forEach(function(file) {
+ if (!fs.existsSync(file)) {
+ error('no such file or directory: ' + file, true);
+ return;
+ }
+
+ var contents = fs.readFileSync(file, 'utf8'),
+ lines = contents.split(/\r*\n/);
+ lines.forEach(function(line) {
+ var matched = line.match(regex);
+ if ((options.inverse && !matched) || (!options.inverse && matched))
+ grep += line + '\n';
+ });
+ });
+
+ return ShellString(grep);
+};
+exports.grep = wrap('grep', _grep);
+
+
+//@
+//@ ### which(command)
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ var nodeExec = which('node');
+//@ ```
+//@
+//@ Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions.
+//@ Returns string containing the absolute path to the command.
+function _which(options, cmd) {
+ if (!cmd)
+ error('must specify command');
+
+ var pathEnv = process.env.path || process.env.Path || process.env.PATH,
+ pathArray = splitPath(pathEnv),
+ where = null;
+
+ // No relative/absolute paths provided?
+ if (cmd.search(/\//) === -1) {
+ // Search for command in PATH
+ pathArray.forEach(function(dir) {
+ if (where)
+ return; // already found it
+
+ var attempt = path.resolve(dir + '/' + cmd);
+ if (fs.existsSync(attempt)) {
+ where = attempt;
+ return;
+ }
+
+ if (platform === 'win') {
+ var baseAttempt = attempt;
+ attempt = baseAttempt + '.exe';
+ if (fs.existsSync(attempt)) {
+ where = attempt;
+ return;
+ }
+ attempt = baseAttempt + '.cmd';
+ if (fs.existsSync(attempt)) {
+ where = attempt;
+ return;
+ }
+ attempt = baseAttempt + '.bat';
+ if (fs.existsSync(attempt)) {
+ where = attempt;
+ return;
+ }
+ } // if 'win'
+ });
+ }
+
+ // Command not found anywhere?
+ if (!fs.existsSync(cmd) && !where)
+ return null;
+
+ where = where || path.resolve(cmd);
+
+ return ShellString(where);
+};
+exports.which = wrap('which', _which);
+
+//@
+//@ ### echo(string [,string ...])
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ echo('hello world');
+//@ var str = echo('hello world');
+//@ ```
+//@
+//@ Prints string to stdout, and returns string with additional utility methods
+//@ like `.to()`.
+function _echo() {
+ var messages = [].slice.call(arguments, 0);
+ console.log.apply(this, messages);
+ return ShellString(messages.join(' '));
+};
+exports.echo = _echo; // don't wrap() as it could parse '-options'
+
+//@
+//@ ### exit(code)
+//@ Exits the current process with the given exit code.
+exports.exit = process.exit;
+
+//@
+//@ ### env['VAR_NAME']
+//@ Object containing environment variables (both getter and setter). Shortcut to process.env.
+exports.env = process.env;
+
+//@
+//@ ### exec(command [, options] [, callback])
+//@ Available options (all `false` by default):
+//@
+//@ + `async`: Asynchronous execution. Defaults to true if a callback is provided.
+//@ + `silent`: Do not echo program output to console.
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ var version = exec('node --version', {silent:true}).output;
+//@
+//@ var child = exec('some_long_running_process', {async:true});
+//@ child.stdout.on('data', function(data) {
+//@ /* ... do something with data ... */
+//@ });
+//@
+//@ exec('some_long_running_process', function(code, output) {
+//@ console.log('Exit code:', code);
+//@ console.log('Program output:', output);
+//@ });
+//@ ```
+//@
+//@ Executes the given `command` _synchronously_, unless otherwise specified.
+//@ When in synchronous mode returns the object `{ code:..., output:... }`, containing the program's
+//@ `output` (stdout + stderr) and its exit `code`. Otherwise returns the child process object, and
+//@ the `callback` gets the arguments `(code, output)`.
+//@
+//@ **Note:** For long-lived processes, it's best to run `exec()` asynchronously as
+//@ the current synchronous implementation uses a lot of CPU. This should be getting
+//@ fixed soon.
+function _exec(command, options, callback) {
+ if (!command)
+ error('must specify command');
+
+ if (typeof options === 'function') {
+ callback = options;
+ options = { async: true };
+ }
+
+ options = extend({
+ silent: state.silent,
+ async: false
+ }, options);
+
+ if (options.async)
+ return execAsync(command, options, callback);
+ else
+ return execSync(command, options);
+};
+exports.exec = wrap('exec', _exec, {notUnix:true});
+
+
+
+
+//@
+//@ ## Non-Unix commands
+//@
+
+
+
+
+
+
+//@
+//@ ### tempdir()
+//@ Searches and returns string containing a writeable, platform-dependent temporary directory.
+//@ Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir).
+exports.tempdir = wrap('tempdir', tempDir);
+
+
+//@
+//@ ### error()
+//@ Tests if error occurred in the last command. Returns `null` if no error occurred,
+//@ otherwise returns string explaining the error
+exports.error = function() {
+ return state.error;
+}
+
+//@
+//@ ### silent([state])
+//@ Example:
+//@
+//@ ```javascript
+//@ var silentState = silent();
+//@ silent(true);
+//@ /* ... */
+//@ silent(silentState); // restore old silent state
+//@ ```
+//@
+//@ Suppresses all command output if `state = true`, except for `echo()` calls.
+//@ Returns state if no arguments given.
+exports.silent = function(_state) {
+ if (typeof _state !== 'boolean')
+ return state.silent;
+
+ state.silent = _state;
+}
+
+
+//@
+//@ ## Deprecated
+//@
+
+
+
+
+//@
+//@ ### exists(path [, path ...])
+//@ ### exists(path_array)
+//@
+//@ _This function is being deprecated. Use `test()` instead._
+//@
+//@ Returns true if all the given paths exist.
+function _exists(options, paths) {
+ deprecate('exists', 'Use test() instead.');
+
+ if (!paths)
+ error('no paths given');
+
+ if (typeof paths === 'string')
+ paths = [].slice.call(arguments, 1);
+ // if it's array leave it as it is
+
+ var exists = true;
+ paths.forEach(function(p) {
+ if (!fs.existsSync(p))
+ exists = false;
+ });
+
+ return exists;
+};
+exports.exists = wrap('exists', _exists);
+
+
+//@
+//@ ### verbose()
+//@
+//@ _This function is being deprecated. Use `silent(false) instead.`_
+//@
+//@ Enables all output (default)
+exports.verbose = function() {
+ deprecate('verbose', 'Use silent(false) instead.');
+
+ state.silent = false;
+}
+
+
+
+
+
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Auxiliary functions (internal use only)
+//
+
+function log() {
+ if (!state.silent)
+ console.log.apply(this, arguments);
+}
+
+function deprecate(what, msg) {
+ console.log('*** ShellJS.'+what+': This function is deprecated.', msg);
+}
+
+function write(msg) {
+ if (!state.silent)
+ process.stdout.write(msg);
+}
+
+// Shows error message. Throws unless '_continue = true'.
+function error(msg, _continue) {
+ if (state.error === null)
+ state.error = '';
+ state.error += state.currentCmd + ': ' + msg + '\n';
+
+ log(state.error);
+
+ if (!_continue)
+ throw '';
+}
+
+// Returns {'alice': true, 'bob': false} when passed:
+// parseOptions('-a', {'a':'alice', 'b':'bob'});
+function parseOptions(str, map) {
+ if (!map)
+ error('parseOptions() internal error: no map given');
+
+ // All options are false by default
+ var options = {};
+ for (var letter in map)
+ options[map[letter]] = false;
+
+ if (!str)
+ return options; // defaults
+
+ if (typeof str !== 'string')
+ error('parseOptions() internal error: wrong str');
+
+ // e.g. match[1] = 'Rf' for str = '-Rf'
+ var match = str.match(/^\-(.+)/);
+ if (!match)
+ return options;
+
+ // e.g. chars = ['R', 'f']
+ var chars = match[1].split('');
+
+ chars.forEach(function(char) {
+ if (char in map)
+ options[map[char]] = true;
+ else
+ error('option not recognized: '+char);
+ });
+
+ return options;
+}
+
+// Common wrapper for all Unix-like commands
+function wrap(cmd, fn, options) {
+ return function() {
+ var retValue = null;
+
+ state.currentCmd = cmd;
+ state.error = null;
+
+ try {
+ var args = [].slice.call(arguments, 0);
+
+ if (options && options.notUnix) {
+ retValue = fn.apply(this, args);
+ } else {
+ if (args.length === 0 || typeof args[0] !== 'string' || args[0][0] !== '-')
+ args.unshift(''); // only add dummy option if '-option' not already present
+ retValue = fn.apply(this, args);
+ }
+ } catch (e) {
+ if (!state.error) {
+ // If state.error hasn't been set it's an error thrown by Node, not us - probably a bug...
+ console.log('shell.js: internal error');
+ console.log(e.stack || e);
+ process.exit(1);
+ }
+ if (state.fatal)
+ throw e;
+ }
+
+ state.currentCmd = 'shell.js';
+ return retValue;
+ }
+} // wrap
+
+// Buffered file copy, synchronous
+// (Using readFileSync() + writeFileSync() could easily cause a memory overflow
+// with large files)
+function copyFileSync(srcFile, destFile) {
+ if (!fs.existsSync(srcFile))
+ error('copyFileSync: no such file or directory: ' + srcFile);
+
+ var BUF_LENGTH = 64*1024,
+ buf = new Buffer(BUF_LENGTH),
+ bytesRead = BUF_LENGTH,
+ pos = 0,
+ fdr = null,
+ fdw = null;
+
+ try {
+ fdr = fs.openSync(srcFile, 'r');
+ } catch(e) {
+ error('copyFileSync: could not read src file ('+srcFile+')');
+ }
+
+ try {
+ fdw = fs.openSync(destFile, 'w');
+ } catch(e) {
+ error('copyFileSync: could not write to dest file (code='+e.code+'):'+destFile);
+ }
+
+ while (bytesRead === BUF_LENGTH) {
+ bytesRead = fs.readSync(fdr, buf, 0, BUF_LENGTH, pos);
+ fs.writeSync(fdw, buf, 0, bytesRead);
+ pos += bytesRead;
+ }
+
+ fs.closeSync(fdr);
+ fs.closeSync(fdw);
+}
+
+// Recursively copies 'sourceDir' into 'destDir'
+// Adapted from https://github.com/ryanmcgrath/wrench-js
+//
+// Copyright (c) 2010 Ryan McGrath
+// Copyright (c) 2012 Artur Adib
+//
+// Licensed under the MIT License
+// http://www.opensource.org/licenses/mit-license.php
+function cpdirSyncRecursive(sourceDir, destDir, opts) {
+ if (!opts) opts = {};
+
+ /* Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */
+ var checkDir = fs.statSync(sourceDir);
+ try {
+ fs.mkdirSync(destDir, checkDir.mode);
+ } catch (e) {
+ //if the directory already exists, that's okay
+ if (e.code !== 'EEXIST') throw e;
+ }
+
+ var files = fs.readdirSync(sourceDir);
+
+ for(var i = 0; i < files.length; i++) {
+ var currFile = fs.lstatSync(sourceDir + "/" + files[i]);
+
+ if (currFile.isDirectory()) {
+ /* recursion this thing right on back. */
+ cpdirSyncRecursive(sourceDir + "/" + files[i], destDir + "/" + files[i], opts);
+ } else if (currFile.isSymbolicLink()) {
+ var symlinkFull = fs.readlinkSync(sourceDir + "/" + files[i]);
+ fs.symlinkSync(symlinkFull, destDir + "/" + files[i]);
+ } else {
+ /* At this point, we've hit a file actually worth copying... so copy it on over. */
+ if (fs.existsSync(destDir + "/" + files[i]) && !opts.force) {
+ log('skipping existing file: ' + files[i]);
+ } else {
+ copyFileSync(sourceDir + "/" + files[i], destDir + "/" + files[i]);
+ }
+ }
+
+ } // for files
+}; // cpdirSyncRecursive
+
+// Recursively removes 'dir'
+// Adapted from https://github.com/ryanmcgrath/wrench-js
+//
+// Copyright (c) 2010 Ryan McGrath
+// Copyright (c) 2012 Artur Adib
+//
+// Licensed under the MIT License
+// http://www.opensource.org/licenses/mit-license.php
+function rmdirSyncRecursive(dir, force) {
+ var files;
+
+ files = fs.readdirSync(dir);
+
+ // Loop through and delete everything in the sub-tree after checking it
+ for(var i = 0; i < files.length; i++) {
+ var file = dir + "/" + files[i],
+ currFile = fs.lstatSync(file);
+
+ if(currFile.isDirectory()) { // Recursive function back to the beginning
+ rmdirSyncRecursive(file, force);
+ }
+
+ else if(currFile.isSymbolicLink()) { // Unlink symlinks
+ if (force || isWriteable(file)) {
+ try {
+ _unlinkSync(file);
+ } catch (e) {
+ error('could not remove file (code '+e.code+'): ' + file, true);
+ }
+ }
+ }
+
+ else // Assume it's a file - perhaps a try/catch belongs here?
+ if (force || isWriteable(file)) {
+ try {
+ _unlinkSync(file);
+ } catch (e) {
+ error('could not remove file (code '+e.code+'): ' + file, true);
+ }
+ }
+ }
+
+ // Now that we know everything in the sub-tree has been deleted, we can delete the main directory.
+ // Huzzah for the shopkeep.
+
+ var result;
+ try {
+ result = fs.rmdirSync(dir);
+ } catch(e) {
+ error('could not remove directory (code '+e.code+'): ' + dir, true);
+ }
+
+ return result;
+}; // rmdirSyncRecursive
+
+// Recursively creates 'dir'
+function mkdirSyncRecursive(dir) {
+ var baseDir = path.dirname(dir);
+
+ // Base dir exists, no recursion necessary
+ if (fs.existsSync(baseDir)) {
+ fs.mkdirSync(dir, 0777);
+ return;
+ }
+
+ // Base dir does not exist, go recursive
+ mkdirSyncRecursive(baseDir);
+
+ // Base dir created, can create dir
+ fs.mkdirSync(dir, 0777);
+};
+
+// e.g. 'makerjs_a5f185d0443ca...'
+function randomFileName() {
+ function randomHash(count) {
+ if (count === 1)
+ return parseInt(16*Math.random()).toString(16);
+ else {
+ var hash = '';
+ for (var i=0; i<count; i++)
+ hash += randomHash(1);
+ return hash;
+ }
+ }
+
+ return 'makerjs_'+randomHash(20);
+}
+
+// Returns false if 'dir' is not a writeable directory, 'dir' otherwise
+function writeableDir(dir) {
+ if (!dir || !fs.existsSync(dir))
+ return false;
+
+ if (!fs.statSync(dir).isDirectory())
+ return false;
+
+ var testFile = dir+'/'+randomFileName();
+ try {
+ fs.writeFileSync(testFile, ' ');
+ _unlinkSync(testFile);
+ return dir;
+ } catch (e) {
+ return false;
+ }
+}
+
+// Cross-platform method for getting an available temporary directory.
+// Follows the algorithm of Python's tempfile.tempdir
+// http://docs.python.org/library/tempfile.html#tempfile.tempdir
+function tempDir() {
+ if (state.tempDir)
+ return state.tempDir; // from cache
+
+ state.tempDir = writeableDir(process.env['TMPDIR']) ||
+ writeableDir(process.env['TEMP']) ||
+ writeableDir(process.env['TMP']) ||
+ writeableDir(process.env['Wimp$ScrapDir']) || // RiscOS
+ writeableDir('C:\\TEMP') || // Windows
+ writeableDir('C:\\TMP') || // Windows
+ writeableDir('\\TEMP') || // Windows
+ writeableDir('\\TMP') || // Windows
+ writeableDir('/tmp') ||
+ writeableDir('/var/tmp') ||
+ writeableDir('/usr/tmp') ||
+ writeableDir('.'); // last resort
+
+ return state.tempDir;
+}
+
+// Wrapper around exec() to enable echoing output to console in real time
+function execAsync(cmd, opts, callback) {
+ var output = '';
+
+ var options = extend({
+ silent: state.silent
+ }, opts);
+
+ var c = child.exec(cmd, {env: process.env}, function(err) {
+ if (callback)
+ callback(err ? err.code : 0, output);
+ });
+
+ c.stdout.on('data', function(data) {
+ output += data;
+ if (!options.silent)
+ process.stdout.write(data);
+ });
+
+ c.stderr.on('data', function(data) {
+ output += data;
+ if (!options.silent)
+ process.stdout.write(data);
+ });
+
+ return c;
+}
+
+// Hack to run child_process.exec() synchronously (sync avoids callback hell)
+// Uses a custom wait loop that checks for a flag file, created when the child process is done.
+// (Can't do a wait loop that checks for internal Node variables/messages as
+// Node is single-threaded; callbacks and other internal state changes are done in the
+// event loop).
+function execSync(cmd, opts) {
+ var stdoutFile = path.resolve(tempDir()+'/'+randomFileName()),
+ codeFile = path.resolve(tempDir()+'/'+randomFileName()),
+ scriptFile = path.resolve(tempDir()+'/'+randomFileName()),
+ sleepFile = path.resolve(tempDir()+'/'+randomFileName());
+
+ var options = extend({
+ silent: state.silent
+ }, opts);
+
+ var previousStdoutContent = '';
+ // Echoes stdout changes from running process, if not silent
+ function updateStdout() {
+ if (options.silent || !fs.existsSync(stdoutFile))
+ return;
+
+ var stdoutContent = fs.readFileSync(stdoutFile, 'utf8');
+ // No changes since last time?
+ if (stdoutContent.length <= previousStdoutContent.length)
+ return;
+
+ process.stdout.write(stdoutContent.substr(previousStdoutContent.length));
+ previousStdoutContent = stdoutContent;
+ }
+
+ function escape(str) {
+ str = str.replace(/\'/g, '"');
+ str = str.replace(/\\/g, '\\\\');
+ return str;
+ }
+
+ cmd += ' > '+stdoutFile+' 2>&1'; // works on both win/unix
+
+ var script =
+ "var child = require('child_process'), \
+ fs = require('fs'); \
+ child.exec('"+escape(cmd)+"', {env: process.env}, function(err) { \
+ fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0'); \
+ });";
+
+ if (fs.existsSync(scriptFile)) _unlinkSync(scriptFile);
+ if (fs.existsSync(stdoutFile)) _unlinkSync(stdoutFile);
+ if (fs.existsSync(codeFile)) _unlinkSync(codeFile);
+
+ fs.writeFileSync(scriptFile, script);
+ child.exec('node '+scriptFile, {
+ env: process.env,
+ cwd: exports.pwd()
+ });
+
+ // The wait loop
+ // sleepFile is used as a dummy I/O op to mitigate unnecessary CPU usage
+ // (tried many I/O sync ops, writeFileSync() seems to be only one that is effective in reducing
+ // CPU usage, though apparently not so much on Windows)
+ while (!fs.existsSync(codeFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); };
+ while (!fs.existsSync(stdoutFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); };
+
+ // At this point codeFile exists, but it's not necessarily flushed yet.
+ // Keep reading it until it is.
+ var code = parseInt('');
+ while (isNaN(code))
+ code = parseInt(fs.readFileSync(codeFile, 'utf8'));
+
+ var stdout = fs.readFileSync(stdoutFile, 'utf8');
+
+ // No biggie if we can't erase the files now -- they're in a temp dir anyway
+ try { _unlinkSync(scriptFile); } catch(e) {};
+ try { _unlinkSync(stdoutFile); } catch(e) {};
+ try { _unlinkSync(codeFile); } catch(e) {};
+ try { _unlinkSync(sleepFile); } catch(e) {};
+
+ // True if successful, false if not
+ var obj = {
+ code: code,
+ output: stdout
+ };
+ return obj;
+} // execSync()
+
+// Expands wildcards with matching file names. For a given array of file names 'list', returns
+// another array containing all file names as per ls(list[i]).
+// For example:
+// expand(['file*.js']) = ['file1.js', 'file2.js', ...]
+// (if the files 'file1.js', 'file2.js', etc, exist in the current dir)
+function expand(list) {
+ var expanded = [];
+ list.forEach(function(listEl) {
+ // Wildcard present?
+ if (listEl.search(/\*/) > -1) {
+ _ls('', listEl).forEach(function(file) {
+ expanded.push(file);
+ });
+ } else {
+ expanded.push(listEl);
+ }
+ });
+ return expanded;
+}
+
+// Cross-platform method for splitting environment PATH variables
+function splitPath(p) {
+ if (!p)
+ return [];
+
+ if (platform === 'win')
+ return p.split(';');
+ else
+ return p.split(':');
+}
+
+// extend(target_obj, source_obj1 [, source_obj2 ...])
+// Shallow extend, e.g.:
+// extend({A:1}, {b:2}, {c:3}) returns {A:1, b:2, c:3}
+function extend(target) {
+ var sources = [].slice.call(arguments, 1);
+ sources.forEach(function(source) {
+ for (var key in source)
+ target[key] = source[key];
+ });
+
+ return target;
+}
+
+// Normalizes _unlinkSync() across platforms to match Unix behavior, i.e.
+// file can be unlinked even if it's read-only, see joyent/node#3006
+function _unlinkSync(file) {
+ try {
+ fs.unlinkSync(file);
+ } catch(e) {
+ // Try to override file permission
+ if (e.code === 'EPERM') {
+ fs.chmodSync(file, '0666');
+ fs.unlinkSync(file);
+ } else {
+ throw e;
+ }
+ }
+}
+
+// Hack to determine if file has write permissions for current user
+// Avoids having to check user, group, etc, but it's probably slow
+function isWriteable(file) {
+ var writePermission = true;
+ try {
+ var __fd = fs.openSync(file, 'a');
+ fs.closeSync(__fd);
+ } catch(e) {
+ writePermission = false;
+ }
+
+ return writePermission;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestnpmignore"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/.npmignore (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/.npmignore (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/.npmignore 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+tmp/
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestcatjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/cat.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/cat.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/cat.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+// save current dir
+var cur = shell.pwd();
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Invalids
+//
+
+shell.cat();
+assert.ok(shell.error());
+
+assert.equal(fs.existsSync('/asdfasdf'), false); // sanity check
+shell.cat('/adsfasdf'); // file does not exist
+assert.ok(shell.error());
+
+//
+// Valids
+//
+
+// simple
+var result = shell.cat('resources/file1');
+assert.equal(shell.error(), null);
+assert.equal(result, 'test1');
+
+// multiple files
+var result = shell.cat('resources/file2', 'resources/file1');
+assert.equal(shell.error(), null);
+assert.equal(result, 'test2\ntest1');
+
+// multiple files, array syntax
+var result = shell.cat(['resources/file2', 'resources/file1']);
+assert.equal(shell.error(), null);
+assert.equal(result, 'test2\ntest1');
+
+var result = shell.cat('resources/file*.txt');
+assert.equal(shell.error(), null);
+assert.ok(result.search('test1') > -1); // file order might be random
+assert.ok(result.search('test2') > -1);
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestcdjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/cd.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/cd.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/cd.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+// save current dir
+var cur = shell.pwd();
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Invalids
+//
+
+shell.cd();
+assert.ok(shell.error());
+
+assert.equal(fs.existsSync('/asdfasdf'), false); // sanity check
+shell.cd('/adsfasdf'); // dir does not exist
+assert.ok(shell.error());
+
+assert.equal(fs.existsSync('resources/file1'), true); // sanity check
+shell.cd('resources/file1'); // file, not dir
+assert.ok(shell.error());
+
+//
+// Valids
+//
+
+shell.cd(cur);
+shell.cd('tmp');
+assert.equal(shell.error(), null);
+assert.equal(path.basename(process.cwd()), 'tmp');
+
+shell.cd(cur);
+shell.cd('/');
+assert.equal(shell.error(), null);
+assert.equal(process.cwd(), path.resolve('/'));
+
+// cd + other commands
+
+shell.cd(cur);
+shell.rm('-f', 'tmp/*');
+assert.equal(fs.existsSync('tmp/file1'), false);
+shell.cd('resources');
+assert.equal(shell.error(), null);
+shell.cp('file1', '../tmp');
+assert.equal(shell.error(), null);
+shell.cd('../tmp');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('file1'), true);
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestcpjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/cp.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/cp.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/cp.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,130 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Invalids
+//
+
+shell.cp();
+assert.ok(shell.error());
+
+shell.cp('file1');
+assert.ok(shell.error());
+
+shell.cp('-f');
+assert.ok(shell.error());
+
+shell.rm('-rf', 'tmp/*');
+shell.cp('-@', 'resources/file1', 'tmp/file1'); // option not supported, files OK
+assert.ok(shell.error());
+assert.equal(fs.existsSync('tmp/file1'), false);
+
+shell.cp('-Z', 'asdfasdf', 'tmp/file2'); // option not supported, files NOT OK
+assert.ok(shell.error());
+assert.equal(fs.existsSync('tmp/file2'), false);
+
+shell.cp('asdfasdf', 'tmp'); // source does not exist
+assert.ok(shell.error());
+assert.equal(numLines(shell.error()), 1);
+assert.equal(fs.existsSync('tmp/asdfasdf'), false);
+
+shell.cp('asdfasdf1', 'asdfasdf2', 'tmp'); // sources do not exist
+assert.ok(shell.error());
+assert.equal(numLines(shell.error()), 2);
+assert.equal(fs.existsSync('tmp/asdfasdf1'), false);
+assert.equal(fs.existsSync('tmp/asdfasdf2'), false);
+
+shell.cp('asdfasdf1', 'asdfasdf2', 'resources/file1'); // too many sources (dest is file)
+assert.ok(shell.error());
+
+shell.cp('resources/file1', 'resources/file2'); // dest already exists
+assert.ok(shell.error());
+
+shell.cp('resources/file1', 'resources/file2', 'tmp/a_file'); // too many sources
+assert.ok(shell.error());
+assert.equal(fs.existsSync('tmp/a_file'), false);
+
+//
+// Valids
+//
+
+// simple - to dir
+shell.cp('resources/file1', 'tmp');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/file1'), true);
+
+// simple - to file
+shell.cp('resources/file2', 'tmp/file2');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/file2'), true);
+
+// simple - file list
+shell.rm('-rf', 'tmp/*');
+shell.cp('resources/file1', 'resources/file2', 'tmp');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/file1'), true);
+assert.equal(fs.existsSync('tmp/file2'), true);
+
+// simple - file list, array syntax
+shell.rm('-rf', 'tmp/*');
+shell.cp(['resources/file1', 'resources/file2'], 'tmp');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/file1'), true);
+assert.equal(fs.existsSync('tmp/file2'), true);
+
+shell.cp('resources/file2', 'tmp/file3');
+assert.equal(fs.existsSync('tmp/file3'), true);
+shell.cp('-f', 'resources/file2', 'tmp/file3'); // file exists, but -f specified
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/file3'), true);
+
+// wildcard
+shell.rm('tmp/file1', 'tmp/file2');
+shell.cp('resources/file*', 'tmp');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/file1'), true);
+assert.equal(fs.existsSync('tmp/file2'), true);
+
+//recursive, nothing exists
+shell.rm('-rf', 'tmp/*');
+shell.cp('-R', 'resources/cp', 'tmp');
+assert.equal(shell.error(), null);
+assert.equal(JSON.stringify(shell.ls('-R', 'resources/cp')), JSON.stringify(shell.ls('-R', 'tmp/cp')));
+
+//recursive, nothing exists, source ends in '/' (see Github issue #15)
+shell.rm('-rf', 'tmp/*');
+shell.cp('-R', 'resources/cp/', 'tmp/');
+assert.equal(shell.error(), null);
+assert.equal(JSON.stringify(shell.ls('-R', 'resources/cp')), JSON.stringify(shell.ls('-R', 'tmp')));
+
+//recursive, everything exists, no force flag
+shell.rm('-rf', 'tmp/*')
+shell.cp('-R', 'resources/cp', 'tmp');
+shell.cp('-R', 'resources/cp', 'tmp');
+assert.equal(shell.error(), null); // crash test only
+
+//recursive, everything exists, with force flag
+shell.rm('-rf', 'tmp/*')
+shell.cp('-R', 'resources/cp', 'tmp');
+'changing things around'.to('tmp/cp/dir_a/z');
+assert.notEqual(shell.cat('resources/cp/dir_a/z'), shell.cat('tmp/cp/dir_a/z')); // before cp
+shell.cp('-Rf', 'resources/cp', 'tmp');
+assert.equal(shell.error(), null);
+assert.equal(shell.cat('resources/cp/dir_a/z'), shell.cat('tmp/cp/dir_a/z')); // after cp
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestechojs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/echo.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/echo.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/echo.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs'),
+ child = require('child_process');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Valids
+//
+
+
+// From here on we use child.exec() to intercept the stdout
+
+
+// simple test with defaults
+shell.mkdir('-p', 'tmp');
+var file = 'tmp/tempscript'+Math.random()+'.js',
+ script = 'require(\'../../global.js\'); echo("-asdf", "111");'; // test '-' bug (see issue #20)
+script.to(file);
+child.exec('node '+file, function(err, stdout, stderr) {
+ assert.ok(stdout === '-asdf 111\n' || stdout === '-asdf 111\nundefined\n'); // 'undefined' for v0.4
+
+ // simple test with silent(true)
+ shell.mkdir('-p', 'tmp');
+ var file = 'tmp/tempscript'+Math.random()+'.js',
+ script = 'require(\'../../global.js\'); silent(true); echo(555);';
+ script.to(file);
+ child.exec('node '+file, function(err, stdout, stderr) {
+ assert.ok(stdout === '555\n' || stdout === '555\nundefined\n'); // 'undefined' for v0.4
+
+ theEnd();
+ });
+});
+
+function theEnd() {
+ shell.exit(123);
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestenvjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/env.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/env.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/env.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert');
+
+shell.silent(true);
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Valids
+//
+
+assert.equal(shell.env['PATH'], process.env['PATH']);
+
+shell.env['MAKERJS_TEST'] = 'hello world';
+assert.equal(shell.env['MAKERJS_TEST'], process.env['MAKERJS_TEST']);
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestexecjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/exec.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/exec.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/exec.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,93 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs'),
+ child = require('child_process');
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+//
+// Invalids
+//
+
+shell.exec();
+assert.ok(shell.error());
+
+var result = shell.exec('asdfasdf'); // could not find command
+assert.ok(result.code > 0);
+
+
+//
+// Valids
+//
+
+//
+// sync
+//
+
+// check if stdout goes to output
+var result = shell.exec('node -e \"console.log(1234);\"');
+assert.equal(shell.error(), null);
+assert.equal(result.code, 0);
+assert.ok(result.output === '1234\n' || result.output === '1234\nundefined\n'); // 'undefined' for v0.4
+
+// check if stderr goes to output
+var result = shell.exec('node -e \"console.error(1234);\"');
+assert.equal(shell.error(), null);
+assert.equal(result.code, 0);
+assert.ok(result.output === '1234\n' || result.output === '1234\nundefined\n'); // 'undefined' for v0.4
+
+// check if stdout + stderr go to output
+var result = shell.exec('node -e \"console.error(1234); console.log(666);\"');
+assert.equal(shell.error(), null);
+assert.equal(result.code, 0);
+assert.ok(result.output === '1234\n666\n' || result.output === '1234\n666\nundefined\n'); // 'undefined' for v0.4
+
+// check exit code
+var result = shell.exec('node -e \"process.exit(12);\"');
+assert.equal(shell.error(), null);
+assert.equal(result.code, 12);
+
+// interaction with cd
+shell.cd('resources/external');
+var result = shell.exec('node node_script.js');
+assert.equal(shell.error(), null);
+assert.equal(result.code, 0);
+assert.equal(result.output, 'node_script_1234\n');
+shell.cd('../..');
+
+//
+// async
+//
+
+// no callback
+var c = shell.exec('node -e \"console.log(1234)\"', {async:true});
+assert.equal(shell.error(), null);
+assert.ok('stdout' in c, 'async exec returns child process object');
+
+//
+// callback as 2nd argument
+//
+shell.exec('node -e \"console.log(5678);\"', function(code, output) {
+ assert.equal(code, 0);
+ assert.ok(output === '5678\n' || output === '5678\nundefined\n'); // 'undefined' for v0.4
+
+ //
+ // callback as 3rd argument
+ //
+ shell.exec('node -e \"console.log(5566);\"', {async:true}, function(code, output) {
+ assert.equal(code, 0);
+ assert.ok(output === '5566\n' || output === '5566\nundefined\n'); // 'undefined' for v0.4
+
+ shell.exit(123);
+
+ });
+
+});
+
+assert.equal(shell.error(), null);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestfindjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/find.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/find.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/find.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Invalids
+//
+
+var result = shell.find(); // no paths given
+assert.ok(shell.error());
+
+//
+// Valids
+//
+
+// current path
+shell.cd('resources/find');
+var result = shell.find('.');
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('.hidden') > -1, true);
+assert.equal(result.indexOf('dir1/dir11/a_dir11') > -1, true);
+assert.equal(result.length, 10);
+shell.cd('../..')
+
+// simple path
+var result = shell.find('resources/find');
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('resources/find/.hidden') > -1, true);
+assert.equal(result.indexOf('resources/find/dir1/dir11/a_dir11') > -1, true);
+assert.equal(result.length, 10);
+
+// multiple paths - comma
+var result = shell.find('resources/find/dir1', 'resources/find/dir2');
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('resources/find/dir1/dir11/a_dir11') > -1, true);
+assert.equal(result.indexOf('resources/find/dir2/a_dir1') > -1, true);
+assert.equal(result.length, 6);
+
+// multiple paths - array
+var result = shell.find(['resources/find/dir1', 'resources/find/dir2']);
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('resources/find/dir1/dir11/a_dir11') > -1, true);
+assert.equal(result.indexOf('resources/find/dir2/a_dir1') > -1, true);
+assert.equal(result.length, 6);
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestgrepjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/grep.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/grep.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/grep.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Invalids
+//
+
+shell.grep();
+assert.ok(shell.error());
+
+shell.grep(/asdf/g); // too few args
+assert.ok(shell.error());
+
+assert.equal(fs.existsSync('/asdfasdf'), false); // sanity check
+shell.grep(/asdf/g, '/asdfasdf'); // no such file
+assert.ok(shell.error());
+
+//
+// Valids
+//
+
+var result = shell.grep('line', 'resources/a.txt');
+assert.equal(shell.error(), null);
+assert.equal(result.split('\n').length - 1, 4);
+
+var result = shell.grep('-v', 'line', 'resources/a.txt');
+assert.equal(shell.error(), null);
+assert.equal(result.split('\n').length - 1, 8);
+
+var result = shell.grep('line one', 'resources/a.txt');
+assert.equal(shell.error(), null);
+assert.equal(result, 'This is line one\n');
+
+// multiple files
+var result = shell.grep(/test/, 'resources/file1.txt', 'resources/file2.txt');
+assert.equal(shell.error(), null);
+assert.equal(result, 'test1\ntest2\n');
+
+// multiple files, array syntax
+var result = shell.grep(/test/, ['resources/file1.txt', 'resources/file2.txt']);
+assert.equal(shell.error(), null);
+assert.equal(result, 'test1\ntest2\n');
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestlsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/ls.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/ls.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/ls.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,202 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Invalids
+//
+
+assert.equal(fs.existsSync('/asdfasdf'), false); // sanity check
+var result = shell.ls('/asdfasdf'); // no such file or dir
+assert.ok(shell.error());
+assert.equal(result.length, 0);
+
+//
+// Valids
+//
+
+var result = shell.ls();
+assert.equal(shell.error(), null);
+
+var result = shell.ls('/');
+assert.equal(shell.error(), null);
+
+// no args
+shell.cd('resources/ls');
+var result = shell.ls();
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('file1') > -1, true);
+assert.equal(result.indexOf('file2') > -1, true);
+assert.equal(result.indexOf('file1.js') > -1, true);
+assert.equal(result.indexOf('file2.js') > -1, true);
+assert.equal(result.indexOf('filename(with)[chars$]^that.must+be-escaped') > -1, true);
+assert.equal(result.indexOf('a_dir') > -1, true);
+assert.equal(result.length, 6);
+shell.cd('../..');
+
+// simple arg
+var result = shell.ls('resources/ls');
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('file1') > -1, true);
+assert.equal(result.indexOf('file2') > -1, true);
+assert.equal(result.indexOf('file1.js') > -1, true);
+assert.equal(result.indexOf('file2.js') > -1, true);
+assert.equal(result.indexOf('filename(with)[chars$]^that.must+be-escaped') > -1, true);
+assert.equal(result.indexOf('a_dir') > -1, true);
+assert.equal(result.length, 6);
+
+// no args, 'all' option
+shell.cd('resources/ls');
+var result = shell.ls('-A');
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('file1') > -1, true);
+assert.equal(result.indexOf('file2') > -1, true);
+assert.equal(result.indexOf('file1.js') > -1, true);
+assert.equal(result.indexOf('file2.js') > -1, true);
+assert.equal(result.indexOf('filename(with)[chars$]^that.must+be-escaped') > -1, true);
+assert.equal(result.indexOf('a_dir') > -1, true);
+assert.equal(result.indexOf('.hidden_file') > -1, true);
+assert.equal(result.indexOf('.hidden_dir') > -1, true);
+assert.equal(result.length, 8);
+shell.cd('../..');
+
+// no args, 'all' option
+shell.cd('resources/ls');
+var result = shell.ls('-a'); // (deprecated) backwards compatibility test
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('file1') > -1, true);
+assert.equal(result.indexOf('file2') > -1, true);
+assert.equal(result.indexOf('file1.js') > -1, true);
+assert.equal(result.indexOf('file2.js') > -1, true);
+assert.equal(result.indexOf('filename(with)[chars$]^that.must+be-escaped') > -1, true);
+assert.equal(result.indexOf('a_dir') > -1, true);
+assert.equal(result.indexOf('.hidden_file') > -1, true);
+assert.equal(result.indexOf('.hidden_dir') > -1, true);
+assert.equal(result.length, 8);
+shell.cd('../..');
+
+// wildcard, simple
+var result = shell.ls('resources/ls/*');
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('resources/ls/file1') > -1, true);
+assert.equal(result.indexOf('resources/ls/file2') > -1, true);
+assert.equal(result.indexOf('resources/ls/file1.js') > -1, true);
+assert.equal(result.indexOf('resources/ls/file2.js') > -1, true);
+assert.equal(result.indexOf('resources/ls/filename(with)[chars$]^that.must+be-escaped') > -1, true);
+assert.equal(result.indexOf('resources/ls/a_dir') > -1, true);
+assert.equal(result.length, 6);
+
+// wildcard, hidden only
+var result = shell.ls('resources/ls/.*');
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('resources/ls/.hidden_file') > -1, true);
+assert.equal(result.indexOf('resources/ls/.hidden_dir') > -1, true);
+assert.equal(result.length, 2);
+
+// wildcard, mid-file
+var result = shell.ls('resources/ls/f*le*');
+assert.equal(shell.error(), null);
+assert.equal(result.length, 5);
+assert.equal(result.indexOf('resources/ls/file1') > -1, true);
+assert.equal(result.indexOf('resources/ls/file2') > -1, true);
+assert.equal(result.indexOf('resources/ls/file1.js') > -1, true);
+assert.equal(result.indexOf('resources/ls/file2.js') > -1, true);
+assert.equal(result.indexOf('resources/ls/filename(with)[chars$]^that.must+be-escaped') > -1, true);
+
+// wildcard, mid-file with dot (should escape dot for regex)
+var result = shell.ls('resources/ls/f*le*.js');
+assert.equal(shell.error(), null);
+assert.equal(result.length, 2);
+assert.equal(result.indexOf('resources/ls/file1.js') > -1, true);
+assert.equal(result.indexOf('resources/ls/file2.js') > -1, true);
+
+// wildcard, should not do partial matches
+var result = shell.ls('resources/ls/*.j'); // shouldn't get .js
+assert.equal(shell.error(), null);
+assert.equal(result.length, 0);
+
+// wildcard, all files with extension
+var result = shell.ls('resources/ls/*.*');
+assert.equal(shell.error(), null);
+assert.equal(result.length, 3);
+assert.equal(result.indexOf('resources/ls/file1.js') > -1, true);
+assert.equal(result.indexOf('resources/ls/file2.js') > -1, true);
+assert.equal(result.indexOf('resources/ls/filename(with)[chars$]^that.must+be-escaped') > -1, true);
+
+// wildcard, with additional path
+var result = shell.ls('resources/ls/f*le*.js', 'resources/ls/a_dir');
+assert.equal(shell.error(), null);
+assert.equal(result.length, 4);
+assert.equal(result.indexOf('resources/ls/file1.js') > -1, true);
+assert.equal(result.indexOf('resources/ls/file2.js') > -1, true);
+assert.equal(result.indexOf('b_dir') > -1, true); // no wildcard == no path prefix
+assert.equal(result.indexOf('nada') > -1, true); // no wildcard == no path prefix
+
+// wildcard for both paths
+var result = shell.ls('resources/ls/f*le*.js', 'resources/ls/a_dir/*');
+assert.equal(shell.error(), null);
+assert.equal(result.length, 4);
+assert.equal(result.indexOf('resources/ls/file1.js') > -1, true);
+assert.equal(result.indexOf('resources/ls/file2.js') > -1, true);
+assert.equal(result.indexOf('resources/ls/a_dir/b_dir') > -1, true);
+assert.equal(result.indexOf('resources/ls/a_dir/nada') > -1, true);
+
+// wildcard for both paths, array
+var result = shell.ls(['resources/ls/f*le*.js', 'resources/ls/a_dir/*']);
+assert.equal(shell.error(), null);
+assert.equal(result.length, 4);
+assert.equal(result.indexOf('resources/ls/file1.js') > -1, true);
+assert.equal(result.indexOf('resources/ls/file2.js') > -1, true);
+assert.equal(result.indexOf('resources/ls/a_dir/b_dir') > -1, true);
+assert.equal(result.indexOf('resources/ls/a_dir/nada') > -1, true);
+
+// recursive, no path
+shell.cd('resources/ls');
+var result = shell.ls('-R');
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('a_dir') > -1, true);
+assert.equal(result.indexOf('a_dir/b_dir') > -1, true);
+assert.equal(result.indexOf('a_dir/b_dir/z') > -1, true);
+assert.equal(result.length, 9);
+shell.cd('../..');
+
+// recusive, path given
+var result = shell.ls('-R', 'resources/ls');
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('a_dir') > -1, true);
+assert.equal(result.indexOf('a_dir/b_dir') > -1, true);
+assert.equal(result.indexOf('a_dir/b_dir/z') > -1, true);
+assert.equal(result.length, 9);
+
+// recusive, path given - 'all' flag
+var result = shell.ls('-RA', 'resources/ls');
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('a_dir') > -1, true);
+assert.equal(result.indexOf('a_dir/b_dir') > -1, true);
+assert.equal(result.indexOf('a_dir/b_dir/z') > -1, true);
+assert.equal(result.indexOf('a_dir/.hidden_dir/nada') > -1, true);
+assert.equal(result.length, 14);
+
+// recursive, wildcard
+var result = shell.ls('-R', 'resources/ls/*');
+assert.equal(shell.error(), null);
+assert.equal(result.indexOf('resources/ls/a_dir') > -1, true);
+assert.equal(result.indexOf('resources/ls/a_dir/b_dir') > -1, true);
+assert.equal(result.indexOf('resources/ls/a_dir/b_dir/z') > -1, true);
+assert.equal(result.length, 9);
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestmkdirjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/mkdir.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/mkdir.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/mkdir.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,79 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Invalids
+//
+
+shell.mkdir();
+assert.ok(shell.error());
+
+var mtime = fs.statSync('tmp').mtime.toString();
+shell.mkdir('tmp'); // dir already exists
+assert.ok(shell.error());
+assert.equal(fs.statSync('tmp').mtime.toString(), mtime); // didn't mess with dir
+
+assert.equal(fs.existsSync('/asdfasdf'), false); // sanity check
+shell.mkdir('/asdfasdf/asdfasdf'); // root path does not exist
+assert.ok(shell.error());
+assert.equal(fs.existsSync('/asdfasdf'), false);
+
+//
+// Valids
+//
+
+assert.equal(fs.existsSync('tmp/t1'), false);
+shell.mkdir('tmp/t1'); // simple dir
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/t1'), true);
+
+assert.equal(fs.existsSync('tmp/t2'), false);
+assert.equal(fs.existsSync('tmp/t3'), false);
+shell.mkdir('tmp/t2', 'tmp/t3'); // multiple dirs
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/t2'), true);
+assert.equal(fs.existsSync('tmp/t3'), true);
+
+assert.equal(fs.existsSync('tmp/t1'), true);
+assert.equal(fs.existsSync('tmp/t4'), false);
+shell.mkdir('tmp/t1', 'tmp/t4'); // one dir exists, one doesn't
+assert.equal(numLines(shell.error()), 1);
+assert.equal(fs.existsSync('tmp/t1'), true);
+assert.equal(fs.existsSync('tmp/t4'), true);
+
+assert.equal(fs.existsSync('tmp/a'), false);
+shell.mkdir('-p', 'tmp/a/b/c');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/a/b/c'), true);
+shell.rm('-Rf', 'tmp/a'); // revert
+
+// multiple dirs
+shell.mkdir('-p', 'tmp/zzza', 'tmp/zzzb', 'tmp/zzzc');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/zzza'), true);
+assert.equal(fs.existsSync('tmp/zzzb'), true);
+assert.equal(fs.existsSync('tmp/zzzc'), true);
+
+// multiple dirs, array syntax
+shell.mkdir('-p', ['tmp/yyya', 'tmp/yyyb', 'tmp/yyyc']);
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/yyya'), true);
+assert.equal(fs.existsSync('tmp/yyyb'), true);
+assert.equal(fs.existsSync('tmp/yyyc'), true);
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestmvjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/mv.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/mv.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/mv.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,130 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+// Prepare tmp/
+shell.cp('resources/*', 'tmp');
+
+//
+// Invalids
+//
+
+shell.mv();
+assert.ok(shell.error());
+
+shell.mv('file1');
+assert.ok(shell.error());
+
+shell.mv('-f');
+assert.ok(shell.error());
+
+shell.mv('-Z', 'tmp/file1', 'tmp/file1'); // option not supported
+assert.ok(shell.error());
+assert.equal(fs.existsSync('tmp/file1'), true);
+
+shell.mv('asdfasdf', 'tmp'); // source does not exist
+assert.ok(shell.error());
+assert.equal(numLines(shell.error()), 1);
+assert.equal(fs.existsSync('tmp/asdfasdf'), false);
+
+shell.mv('asdfasdf1', 'asdfasdf2', 'tmp'); // sources do not exist
+assert.ok(shell.error());
+assert.equal(numLines(shell.error()), 2);
+assert.equal(fs.existsSync('tmp/asdfasdf1'), false);
+assert.equal(fs.existsSync('tmp/asdfasdf2'), false);
+
+shell.mv('asdfasdf1', 'asdfasdf2', 'tmp/file1'); // too many sources (dest is file)
+assert.ok(shell.error());
+
+shell.mv('tmp/file1', 'tmp/file2'); // dest already exists
+assert.ok(shell.error());
+
+shell.mv('tmp/file1', 'tmp/file2', 'tmp/a_file'); // too many sources (exist, but dest is file)
+assert.ok(shell.error());
+assert.equal(fs.existsSync('tmp/a_file'), false);
+
+shell.mv('tmp/file*', 'tmp/file1'); // can't use wildcard when dest is file
+assert.ok(shell.error());
+assert.equal(fs.existsSync('tmp/file1'), true);
+assert.equal(fs.existsSync('tmp/file2'), true);
+assert.equal(fs.existsSync('tmp/file1.js'), true);
+assert.equal(fs.existsSync('tmp/file2.js'), true);
+
+//
+// Valids
+//
+
+shell.cd('tmp');
+
+// handles self OK
+shell.mkdir('tmp2');
+shell.mv('*', 'tmp2'); // has to handle self (tmp2 --> tmp2) without throwing error
+assert.ok(shell.error()); // there's an error, but not fatal
+assert.equal(fs.existsSync('tmp2/file1'), true); // moved OK
+shell.mv('tmp2/*', '.'); // revert
+assert.equal(fs.existsSync('file1'), true); // moved OK
+
+shell.mv('file1', 'file3'); // one source
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('file1'), false);
+assert.equal(fs.existsSync('file3'), true);
+shell.mv('file3', 'file1'); // revert
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('file1'), true);
+
+// two sources
+shell.rm('-rf', 't');
+shell.mkdir('-p', 't');
+shell.mv('file1', 'file2', 't');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('file1'), false);
+assert.equal(fs.existsSync('file2'), false);
+assert.equal(fs.existsSync('t/file1'), true);
+assert.equal(fs.existsSync('t/file2'), true);
+shell.mv('t/*', '.'); // revert
+assert.equal(fs.existsSync('file1'), true);
+assert.equal(fs.existsSync('file2'), true);
+
+// two sources, array style
+shell.rm('-rf', 't');
+shell.mkdir('-p', 't');
+shell.mv(['file1', 'file2'], 't'); // two sources
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('file1'), false);
+assert.equal(fs.existsSync('file2'), false);
+assert.equal(fs.existsSync('t/file1'), true);
+assert.equal(fs.existsSync('t/file2'), true);
+shell.mv('t/*', '.'); // revert
+assert.equal(fs.existsSync('file1'), true);
+assert.equal(fs.existsSync('file2'), true);
+
+shell.mv('file*.js', 't'); // wildcard
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('file1.js'), false);
+assert.equal(fs.existsSync('file2.js'), false);
+assert.equal(fs.existsSync('t/file1.js'), true);
+assert.equal(fs.existsSync('t/file2.js'), true);
+shell.mv('t/*', '.'); // revert
+assert.equal(fs.existsSync('file1.js'), true);
+assert.equal(fs.existsSync('file2.js'), true);
+
+shell.mv('-f', 'file1', 'file2'); // dest exists, but -f given
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('file1'), false);
+assert.equal(fs.existsSync('file2'), true);
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestpwdjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/pwd.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/pwd.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/pwd.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path');
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Valids
+//
+
+var _pwd = shell.pwd();
+assert.equal(shell.error(), null);
+assert.equal(_pwd, path.resolve('.'));
+
+shell.cd('tmp');
+var _pwd = shell.pwd();
+assert.equal(shell.error(), null);
+assert.equal(path.basename(_pwd), 'tmp');
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesatxt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/a.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/a.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/a.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+This is line one
+This is line two
+
+This is line four
+.
+.
+More content here
+.
+.
+
+This is line eleven
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcescpa"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/a (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/a (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/a 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcescpb"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/b (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/b (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/b 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcescpdir_az"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/dir_a/z (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/dir_a/z (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/dir_a/z 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcescpdir_bdir_b_adir_b_a_az"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/dir_b/dir_b_a/dir_b_a_a/z (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/dir_b/dir_b_a/dir_b_a_a/z (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/cp/dir_b/dir_b_a/dir_b_a_a/z 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesexternalnode_scriptjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/node_script.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/node_script.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/node_script.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+console.log('node_script_1234');
+
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/node_script.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesexternaltmpoutput"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/tmp/output ( => )</h4>
<pre class="diff"><span>
<span class="info">Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/tmp/tempscript.js
===================================================================
</span><del>--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/tmp/tempscript.js (rev 0)
</del><ins>+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/external/tmp/tempscript.js 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="lines">@@ -0,0 +1 @@
</span><ins>+throw __dirname; require('../../global.js'); silent(false); exec('node -e "console.log(1234);"', {silent:false})
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfile1"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file1 (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file1 (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file1 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+test1
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfile1js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file1.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file1.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file1.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+test
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfile1txt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file1.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file1.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file1.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+test1
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfile2"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file2 (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file2 (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file2 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+test2
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfile2js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file2.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file2.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file2.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+test
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfile2txt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file2.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file2.txt (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/file2.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+test2
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfindhidden"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/.hidden (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/.hidden (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/.hidden 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfinda"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/a (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/a (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/a 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfindb"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/b (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/b (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/b 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfinddir1a_dir1"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir1/a_dir1 (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir1/a_dir1 (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir1/a_dir1 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfinddir1dir11a_dir11"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir1/dir11/a_dir11 (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir1/dir11/a_dir11 (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir1/dir11/a_dir11 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourcesfinddir2a_dir1"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir2/a_dir1 (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir2/a_dir1 (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/find/dir2/a_dir1 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslshidden_dirnada"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/.hidden_dir/nada (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/.hidden_dir/nada (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/.hidden_dir/nada 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslshidden_file"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/.hidden_file (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/.hidden_file (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/.hidden_file 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsa_dirhidden_dirnada"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/.hidden_dir/nada (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/.hidden_dir/nada (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/.hidden_dir/nada 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+nada
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsa_dirb_dirz"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/b_dir/z (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/b_dir/z (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/b_dir/z 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsa_dirnada"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/nada (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/nada (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/a_dir/nada 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsfile1"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file1 (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file1 (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file1 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+test
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsfile1js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file1.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file1.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file1.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+test
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsfile2"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file2 (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file2 (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file2 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+test
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsfile2js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file2.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file2.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/file2.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+test
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestresourceslsfilenamewithcharsthatmustbeescaped"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/filename(with)[chars$]^that.must+be-escaped (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/filename(with)[chars$]^that.must+be-escaped (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/resources/ls/filename(with)[chars$]^that.must+be-escaped 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+asdf
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestrmjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/rm.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/rm.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/rm.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,183 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp');
+
+//
+// Invalids
+//
+
+shell.rm();
+assert.ok(shell.error());
+
+shell.rm('asdfasdf'); // file does not exist
+assert.ok(shell.error());
+
+shell.rm('-f'); // no file
+assert.ok(shell.error());
+
+shell.rm('-@', 'resources/file1'); // invalid option
+assert.ok(shell.error());
+assert.equal(fs.existsSync('resources/file1'), true);
+
+//
+// Valids
+//
+
+// file does not exist, but -f specified
+shell.rm('-f', 'asdfasdf');
+assert.equal(shell.error(), null);
+
+ // simple rm
+ shell.cp('-f', 'resources/file1', 'tmp/file1');
+assert.equal(fs.existsSync('tmp/file1'), true);
+shell.rm('tmp/file1');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/file1'), false);
+
+// recursive dir removal - small-caps '-r'
+shell.mkdir('-p', 'tmp/a/b/c');
+assert.equal(fs.existsSync('tmp/a/b/c'), true);
+shell.rm('-rf', 'tmp/a');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/a'), false);
+
+// recursive dir removal - capital '-R'
+shell.mkdir('-p', 'tmp/a/b/c');
+assert.equal(fs.existsSync('tmp/a/b/c'), true);
+shell.rm('-Rf', 'tmp/a');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/a'), false);
+
+// recursive dir removal - absolute path
+shell.mkdir('-p', 'tmp/a/b/c');
+assert.equal(fs.existsSync('tmp/a/b/c'), true);
+shell.rm('-Rf', path.resolve('./tmp/a'));
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/a'), false);
+
+// wildcard
+shell.cp('-f', 'resources/file*', 'tmp');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/file1'), true);
+assert.equal(fs.existsSync('tmp/file2'), true);
+assert.equal(fs.existsSync('tmp/file1.js'), true);
+assert.equal(fs.existsSync('tmp/file2.js'), true);
+shell.rm('tmp/file*');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync('tmp/file1'), false);
+assert.equal(fs.existsSync('tmp/file2'), false);
+assert.equal(fs.existsSync('tmp/file1.js'), false);
+assert.equal(fs.existsSync('tmp/file2.js'), false);
+
+// recursive dir removal
+shell.mkdir('-p', 'tmp/a/b/c');
+shell.mkdir('-p', 'tmp/b');
+shell.mkdir('-p', 'tmp/c');
+shell.mkdir('-p', 'tmp/.hidden');
+assert.equal(fs.existsSync('tmp/a/b/c'), true);
+assert.equal(fs.existsSync('tmp/b'), true);
+assert.equal(fs.existsSync('tmp/c'), true);
+assert.equal(fs.existsSync('tmp/.hidden'), true);
+shell.rm('-rf', 'tmp/*');
+assert.equal(shell.error(), null);
+var contents = fs.readdirSync('tmp');
+assert.equal(contents.length, 1);
+assert.equal(contents[0], '.hidden'); // shouldn't remove hiddden if no .* given
+
+// recursive dir removal
+shell.mkdir('-p', 'tmp/a/b/c');
+shell.mkdir('-p', 'tmp/b');
+shell.mkdir('-p', 'tmp/c');
+shell.mkdir('-p', 'tmp/.hidden');
+assert.equal(fs.existsSync('tmp/a/b/c'), true);
+assert.equal(fs.existsSync('tmp/b'), true);
+assert.equal(fs.existsSync('tmp/c'), true);
+assert.equal(fs.existsSync('tmp/.hidden'), true);
+shell.rm('-rf', 'tmp/*', 'tmp/.*');
+assert.equal(shell.error(), null);
+var contents = fs.readdirSync('tmp');
+assert.equal(contents.length, 0);
+
+// recursive dir removal - array-syntax
+shell.mkdir('-p', 'tmp/a/b/c');
+shell.mkdir('-p', 'tmp/b');
+shell.mkdir('-p', 'tmp/c');
+shell.mkdir('-p', 'tmp/.hidden');
+assert.equal(fs.existsSync('tmp/a/b/c'), true);
+assert.equal(fs.existsSync('tmp/b'), true);
+assert.equal(fs.existsSync('tmp/c'), true);
+assert.equal(fs.existsSync('tmp/.hidden'), true);
+shell.rm('-rf', ['tmp/*', 'tmp/.*']);
+assert.equal(shell.error(), null);
+var contents = fs.readdirSync('tmp');
+assert.equal(contents.length, 0);
+
+// removal of a read-only file (unforced)
+shell.mkdir('-p', 'tmp/readonly');
+'asdf'.to('tmp/readonly/file1');
+fs.chmodSync('tmp/readonly/file1', '0444'); // -r--r--r--
+shell.rm('tmp/readonly/file1');
+assert.equal(fs.existsSync('tmp/readonly/file1'), true); // bash's rm always asks before removing read-only files
+ // here we just assume "no"
+
+// removal of a read-only file (forced)
+shell.mkdir('-p', 'tmp/readonly');
+'asdf'.to('tmp/readonly/file2');
+fs.chmodSync('tmp/readonly/file2', '0444'); // -r--r--r--
+shell.rm('-f', 'tmp/readonly/file2');
+assert.equal(fs.existsSync('tmp/readonly/file2'), false);
+
+// removal of a tree containing read-only files (unforced)
+shell.mkdir('-p', 'tmp/tree2');
+'asdf'.to('tmp/tree2/file1');
+'asdf'.to('tmp/tree2/file2');
+fs.chmodSync('tmp/tree2/file1', '0444'); // -r--r--r--
+shell.rm('-r', 'tmp/tree2');
+assert.equal(fs.existsSync('tmp/tree2/file1'), true);
+assert.equal(fs.existsSync('tmp/tree2/file2'), false);
+
+// removal of a tree containing read-only files (forced)
+shell.mkdir('-p', 'tmp/tree');
+'asdf'.to('tmp/tree/file1');
+'asdf'.to('tmp/tree/file2');
+fs.chmodSync('tmp/tree/file1', '0444'); // -r--r--r--
+shell.rm('-rf', 'tmp/tree');
+assert.equal(fs.existsSync('tmp/tree'), false);
+
+// removal of a sub-tree containing read-only and hidden files - rm('dir/*')
+shell.mkdir('-p', 'tmp/tree3');
+shell.mkdir('-p', 'tmp/tree3/subtree');
+shell.mkdir('-p', 'tmp/tree3/.hidden');
+'asdf'.to('tmp/tree3/subtree/file');
+'asdf'.to('tmp/tree3/.hidden/file');
+'asdf'.to('tmp/tree3/file');
+fs.chmodSync('tmp/tree3/file', '0444'); // -r--r--r--
+fs.chmodSync('tmp/tree3/subtree/file', '0444'); // -r--r--r--
+fs.chmodSync('tmp/tree3/.hidden/file', '0444'); // -r--r--r--
+shell.rm('-rf', 'tmp/tree3/*', 'tmp/tree3/.*'); // erase dir contents
+assert.equal(shell.ls('tmp/tree3').length, 0);
+
+// removal of a sub-tree containing read-only and hidden files - rm('dir')
+shell.mkdir('-p', 'tmp/tree4');
+shell.mkdir('-p', 'tmp/tree4/subtree');
+shell.mkdir('-p', 'tmp/tree4/.hidden');
+'asdf'.to('tmp/tree4/subtree/file');
+'asdf'.to('tmp/tree4/.hidden/file');
+'asdf'.to('tmp/tree4/file');
+fs.chmodSync('tmp/tree4/file', '0444'); // -r--r--r--
+fs.chmodSync('tmp/tree4/subtree/file', '0444'); // -r--r--r--
+fs.chmodSync('tmp/tree4/.hidden/file', '0444'); // -r--r--r--
+shell.rm('-rf', 'tmp/tree4'); // erase dir contents
+assert.equal(fs.existsSync('tmp/tree4'), false);
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestsedjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/sed.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/sed.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/sed.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,58 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Invalids
+//
+
+shell.sed();
+assert.ok(shell.error());
+
+shell.sed(/asdf/g); // too few args
+assert.ok(shell.error());
+
+shell.sed(/asdf/g, 'nada'); // too few args
+assert.ok(shell.error());
+
+assert.equal(fs.existsSync('/asdfasdf'), false); // sanity check
+shell.sed(/asdf/g, 'nada', '/asdfasdf'); // no such file
+assert.ok(shell.error());
+
+//
+// Valids
+//
+
+shell.cp('-f', 'resources/file1', 'tmp/file1')
+var result = shell.sed('test1', 'hello', 'tmp/file1'); // search string
+assert.equal(shell.error(), null);
+assert.equal(result, 'hello');
+
+var result = shell.sed(/test1/, 'hello', 'tmp/file1'); // search regex
+assert.equal(shell.error(), null);
+assert.equal(result, 'hello');
+
+var result = shell.sed(/test1/, 1234, 'tmp/file1'); // numeric replacement
+assert.equal(shell.error(), null);
+assert.equal(result, '1234');
+
+var result = shell.sed('-i', /test1/, 'hello', 'tmp/file1');
+assert.equal(shell.error(), null);
+assert.equal(result, 'hello');
+assert.equal(shell.cat('tmp/file1'), 'hello');
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestsilentjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/silent.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/silent.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/silent.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+//
+// Valids
+//
+
+assert.equal(shell.silent(), false); // default
+
+shell.silent(true);
+assert.equal(shell.silent(), true);
+
+shell.silent(false);
+assert.equal(shell.silent(), false);
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstesttempdirjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/tempdir.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/tempdir.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/tempdir.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Valids
+//
+
+var tmp = shell.tempdir();
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync(tmp), true);
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstesttestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/test.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/test.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/test.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,83 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Invalids
+//
+
+var result = shell.test(); // no expression given
+assert.ok(shell.error());
+
+var result = shell.test('asdf'); // bad expression
+assert.ok(shell.error());
+
+var result = shell.test('f', 'resources/file1'); // bad expression
+assert.ok(shell.error());
+
+var result = shell.test('-f'); // no file
+assert.ok(shell.error());
+
+//
+// Valids
+//
+
+//exists
+var result = shell.test('-e', 'resources/file1');
+assert.equal(shell.error(), null);
+assert.equal(result, true);//true
+
+var result = shell.test('-e', 'resources/404');
+assert.equal(shell.error(), null);
+assert.equal(result, false);
+
+//directory
+var result = shell.test('-d', 'resources');
+assert.equal(shell.error(), null);
+assert.equal(result, true);//true
+
+var result = shell.test('-f', 'resources');
+assert.equal(shell.error(), null);
+assert.equal(result, false);
+
+var result = shell.test('-L', 'resources');
+assert.equal(shell.error(), null);
+assert.equal(result, false);
+
+//file
+var result = shell.test('-d', 'resources/file1');
+assert.equal(shell.error(), null);
+assert.equal(result, false);
+
+var result = shell.test('-f', 'resources/file1');
+assert.equal(shell.error(), null);
+assert.equal(result, true);//true
+
+var result = shell.test('-L', 'resources/file1');
+assert.equal(shell.error(), null);
+assert.equal(result, false);
+
+//link
+var result = shell.test('-d', 'resources/link');
+assert.equal(shell.error(), null);
+assert.equal(result, false);
+
+var result = shell.test('-f', 'resources/link');
+assert.equal(shell.error(), null);
+assert.equal(result, true);//true
+
+var result = shell.test('-L', 'resources/link');
+assert.equal(shell.error(), null);
+assert.equal(result, true);//true
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstesttojs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/to.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/to.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/to.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Invalids
+//
+
+'hello world'.to();
+assert.ok(shell.error());
+
+assert.equal(fs.existsSync('/asdfasdf'), false); // sanity check
+'hello world'.to('/asdfasdf/file');
+assert.ok(shell.error());
+
+//
+// Valids
+//
+
+'hello world'.to('tmp/to1');
+var result = shell.cat('tmp/to1');
+assert.equal(shell.error(), null);
+assert.equal(result, 'hello world');
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolsnode_modulesshelljstestwhichjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/which.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/which.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/node_modules/shelljs/test/which.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+var shell = require('..');
+
+var assert = require('assert'),
+ path = require('path'),
+ fs = require('fs');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+shell.silent(true);
+
+function numLines(str) {
+ return typeof str === 'string' ? str.match(/\n/g).length : 0;
+}
+
+shell.rm('-rf', 'tmp');
+shell.mkdir('tmp')
+
+//
+// Invalids
+//
+
+shell.which();
+assert.ok(shell.error());
+
+var result = shell.which('asdfasdfasdfasdfasdf'); // what are the odds...
+assert.equal(shell.error(), null);
+assert.equal(result, null);
+
+//
+// Valids
+//
+
+var result = shell.which('node');
+assert.equal(shell.error(), null);
+assert.equal(fs.existsSync(result), true);
+
+shell.exit(123);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxindexhtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/index.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/index.html (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/index.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+<!doctype html>
+<html>
+ <head>
+ <script src="../../../enyo.js" type="text/javascript"></script>
+ <script src="package.js" type="text/javascript"></script>
+ <script src="tests/package.js" type="text/javascript"></script>
+ </head>
+ <body style="font-size: medium">
+ <script type="text/javascript">
+ new enyo.TestRunner().write();
+ </script>
+ </body>
+</html>
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxpackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+enyo.depends(
+ "$lib/extra/test"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxphpredballjpg"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/redball.jpg</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/redball.jpg
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/redball.jpg 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/redball.jpg 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/redball.jpg
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/jpeg
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkenyotoolstestajaxphptest1php"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test1.php (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test1.php (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test1.php 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+<?php
+$format = @$_GET['format'];
+$callback = @$_GET['callback'];
+if ($format == 'text') {
+ echo 'hello';
+} elseif ($format == 'xml') {
+ header('Content-Type: text/xml');
+ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' . "\n";
+ echo "<response>hello</response>";
+} elseif ($format == 'jsonp') {
+ header('Content-Type: text/javascript');
+ echo "$callback(";
+ echo json_encode(array('response' => 'hello', 'utf8' => 'Ви́хри'));
+ echo ');';
+} else {
+ echo json_encode(array('response' => 'hello'));
+}
+?>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxphptest2php"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test2.php (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test2.php (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test2.php 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+<?php
+$method = @$_SERVER['REQUEST_METHOD'];
+switch ($method) {
+ case 'GET':
+ get();
+ break;
+ case 'POST':
+ post();
+ break;
+ case 'DELETE':
+ delete();
+ break;
+ case 'PUT':
+ put();
+ break;
+ default:
+ echo "invalid method";
+}
+
+function get() {
+ $result = array('status' => "get");
+ echo json_encode($result);
+}
+
+function post() {
+ $q = @$_POST['query'];
+ if ($q) {
+ $result = array('response' => "post.".$q);
+ } else {
+ $q = @$_GET['query'];
+ if ($q) {
+ $result = array('response' => "query.".$q);
+ }else{
+ $result = array('response' => file_get_contents('php://input'));
+ }
+ }
+ $requested_with = @$_SERVER['HTTP_X_REQUESTED_WITH'];
+ if ($requested_with == 'XMLHttpRequest') {
+ $result['isAjax'] = true;
+ }
+ echo json_encode($result);
+}
+
+function put() {
+ $c = @$_SERVER["CONTENT_TYPE"];
+ $result = array('status' => "put", 'ctype' => $c);
+ echo json_encode($result);
+}
+
+function delete() {
+ $result = array('status' => "delete");
+ echo json_encode($result);
+}
+?>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxphptest3php"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test3.php (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test3.php (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test3.php 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+<?php
+$method = @$_SERVER['REQUEST_METHOD'];
+switch ($method) {
+ case 'GET':
+ get();
+ break;
+ default:
+ echo "invalid method";
+}
+
+function get() {
+ sleep(3);
+ $result = array('status' => "get");
+ echo json_encode($result);
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxphptest4php"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test4.php (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test4.php (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test4.php 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<?php
+$method = @$_SERVER['REQUEST_METHOD'];
+switch ($method) {
+ case 'POST':
+ post();
+ break;
+ default:
+ echo "invalid method";
+}
+
+function post() {
+ $ctype = @$_SERVER["CONTENT_TYPE"];
+ $cacheCtrl = @$_SERVER["HTTP_CACHE_CONTROL"];
+ $result = array('status' => "post" , 'ctype' => $ctype , 'cacheCtrl' => $cacheCtrl);
+ echo json_encode($result);
+
+ # useful for test setup...
+ #foreach ($_SERVER as $name => $value) {
+ # echo "$name: $value\n";
+ #}
+}
+?>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxphptest5php"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test5.php (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test5.php (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test5.php 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+<?php
+$method = @$_SERVER['REQUEST_METHOD'];
+switch ($method) {
+ case 'GET':
+ // Set a custom HTTP response code: pick a working one (no clue)
+ //$this->header('HTTP/1.1 500: Internal Server Error');
+ //header('HTTP/1.1 500 Internal Server Error');
+ //http_response_code(500); // php >= 5.4
+ header('X-PHP-Response-Code: 500', true, 500); // php >= 4.3
+
+ // can't use odd charset due to IE exception throwing
+ //header('Content-Type: text/plain; charset=x-user-unparseable');
+ header('Content-Type: text/plain; charset=utf-8');
+
+ echo "my error description";
+ break;
+ default:
+ echo "invalid method";
+}
+?>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxphptest6php"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test6.php (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test6.php (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/php/test6.php 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+<?php
+$method = @$_SERVER['REQUEST_METHOD'];
+switch ($method) {
+ case 'GET':
+ get();
+ break;
+ default:
+ echo "invalid method";
+}
+
+function get() {
+ sleep(3);
+ $result = array('status' => "get");
+ echo json_encode($result);
+
+ # $attachment_location = $_SERVER["DOCUMENT_ROOT"] . "/file.zip";
+ $attachment_location = "redball.jpg";
+ if (file_exists($attachment_location)) {
+
+ header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
+ header("Cache-Control: public"); // needed for i.e.
+ header("Content-Type: image/jpeg");
+ header("Content-Transfer-Encoding: Binary");
+ header("Content-Length:".filesize($attachment_location));
+ header("Content-Disposition: attachment; filename=redball.jpg");
+ readfile($attachment_location);
+ die();
+ } else {
+ die("Error: File not found.");
+ }
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxtestsAjaxTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/AjaxTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/AjaxTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/AjaxTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,246 @@
</span><ins>+enyo.kind({
+ name: "AjaxTest",
+ kind: enyo.TestSuite,
+ timeout: 10000,
+ testContextSuccess: function (){
+ var self = this,
+ context = {testStatus: 'success'};
+ return new enyo.Ajax({url: "php/test1.php?format=test"})
+ .response(context, function(inSender, inValue) {
+ if (this.testStatus && this.testStatus === 'success') {
+ self.finish("");
+ } else {
+ self.finish("response context not correctly bound");
+ }
+ })
+ .error(context, function(inSender, inError) {
+ self.finish("simple request failed");
+ })
+ .go();
+ },
+ testContextFailure: function (){
+ var self = this,
+ context = {testStatus: 'success'};
+ return new enyo.Ajax({url: "php/nowhere.php"})
+ .response(context, function(inSender, inValue) {
+ self.finish("simple request failed");
+ })
+ .error(context, function(inSender, inError) {
+ if (this.testStatus && this.testStatus === 'success') {
+ self.finish("");
+ } else {
+ self.finish("failure context not correctly bound");
+ }
+ })
+ .go();
+ },
+ _testAjax: function(inProps, inParams, inAssertFn, inAssertErrFn) {
+ return new enyo.Ajax(inProps)
+ .response(this, function(inSender, inValue) {
+ this.finish(inAssertFn.call(null, inValue) ? "" : "bad response: " + JSON.stringify(inValue));
+ })
+ .error(this, function(inSender, inError) {
+ if (!inAssertErrFn) {
+ this.finish("bad status: " + inError.toString());
+ enyo.error(inError);
+ enyo.error(inError.stack);
+ } else {
+ this.finish(inAssertErrFn.call(null, inError) ? "" : "bad response: " + inError);
+ }
+ })
+ .go(inParams);
+ },
+ _testResponse: function(inProps, inAssertFn) {
+ this._testAjax(enyo.mixin({url: "php/test1.php?format=" + inProps.handleAs}, inProps), null, inAssertFn);
+ },
+ testJsonResponse: function() {
+ this._testResponse({handleAs: "json"}, function(inValue) {
+ return inValue.response == "hello";
+ });
+ },
+ testTextResponse: function() {
+ this._testResponse({handleAs: "text"}, function(inValue) {
+ return inValue == "hello";
+ });
+ },
+ testXmlResponse: function() {
+ this._testResponse({handleAs: "xml"}, function(inValue) {
+ var r = inValue.getElementsByTagName("response")[0].childNodes[0].nodeValue;
+ return r == "hello";
+ });
+ },
+ testSyncTextResponse: function() {
+ this._testResponse({handleAs: "text", sync: true}, function(inValue) {
+ return inValue == "hello";
+ });
+ },
+ // try a post with query object
+ testPostRequestQuery: function() {
+ this._testAjax({url: "php/test2.php", method: "POST"}, {query: "enyo"}, function(inValue) {
+ return inValue.response == "query.enyo";
+ });
+ },
+ testPostRequestQueryWithPayload: function() {
+ this._testAjax({url: "php/test2.php", method: "POST", postBody:"data"}, {query: "enyo"}, function(inValue) {
+ return inValue.response == "query.enyo";
+ });
+ },
+ testPostRequestPayload: function() {
+ this._testAjax({url: "php/test2.php", method: "POST", postBody:"query=enyo"}, null, function(inValue) {
+ return inValue.response == "post.enyo";
+ });
+ },
+ testPutRequest: function() {
+ this._testAjax({url: "php/test2.php", method: "PUT"}, null, function(inValue) {
+ return inValue.status == "put";
+ });
+ },
+ testDeleteRequest: function() {
+ this._testAjax({url: "php/test2.php", method: "DELETE"}, null, function(inValue) {
+ return inValue.status == "delete";
+ });
+ },
+ testHeader: function() {
+ this._testAjax({url: "php/test2.php", method: "POST", headers: {"X-Requested-With": "XMLHttpRequest"}}, {query: "enyo"}, function(inValue) {
+ return inValue.isAjax;
+ });
+ },
+ testPostBody: function() {
+ this._testAjax({url: "php/test2.php", method: "POST", postBody: "This is a test."}, null, function(inValue) {
+ return inValue.response == "This is a test.";
+ });
+ },
+ testContentType: function() {
+ var contentType = "text/plain";
+ this._testAjax({url: "php/test2.php", method: "PUT", contentType: contentType}, null, function(inValue) {
+ return (inValue.ctype === contentType);
+ });
+ },
+ testCacheControlOn: function() {
+ // skip test on non-iOS platforms, since Firefox always sends cache-control header causing
+ // false positive
+ if (!enyo.platform.ios) {
+ this.finish();
+ return;
+ }
+ var contentType = "application/x-www-form-urlencoded";
+ this._testAjax({url: "php/test4.php", method: "POST", postBody: "data"}, null, function(inValue) {
+ if (enyo.platform.ios && enyo.platform.ios >= 6) {
+ var status = inValue.cacheCtrl && (inValue.cacheCtrl.indexOf('no-cache') === 0);
+ if (!status) {
+ enyo.log("Bad Cache-Control: " + inValue.cacheCtrl + " expected: " + "no-cache");
+ }
+ return status;
+ } else {
+ return true;
+ }
+ });
+ },
+ testCacheControlOff: function() {
+ // skip test on non-iOS platforms, since Firefox always sends cache-control header causing
+ // false positive
+ if (!enyo.platform.ios) {
+ this.finish();
+ return;
+ }
+ var contentType = "application/x-www-form-urlencoded";
+ this._testAjax({url: "php/test4.php", method: "POST", postBody: "data", headers: {'cache-control': null} }, null, function(inValue) {
+ var status = (inValue.cacheCtrl === null);
+ if (!status) {
+ enyo.log("Bad Cache-Control: " + inValue.cacheCtrl + " expected: " + undefined);
+ }
+ return status;
+ });
+ },
+ testContentTypeDefault: function() {
+ var contentType = "application/x-www-form-urlencoded";
+ this._testAjax({url: "php/test4.php", method: "POST", postBody: "data"}, null, function(inValue) {
+ var status = (inValue.ctype.indexOf(contentType) === 0);
+ if (!status) {
+ enyo.log("Bad CT: " + inValue.ctype + " expected: " + contentType);
+ }
+ return status;
+ });
+ },
+ testContentTypeFormDataField: function() {
+ var formData = new enyo.FormData();
+ formData.append('token', "data");
+ var contentType = "multipart/form-data";
+ this._testAjax({url: "php/test4.php", method: "POST", postBody: formData}, null, function(inValue) {
+ var status = (inValue.ctype.indexOf(contentType) === 0) &&
+ (inValue.ctype.indexOf("boundary=--") > 10);
+ if (!status) {
+ enyo.log("Bad CT: " + inValue.ctype + " expected: " + contentType);
+ }
+ return status;
+ });
+ },
+ testContentTypeFormDataFile: function() {
+ var formData = new enyo.FormData();
+ var file = new enyo.Blob(["Some Random File Content!", "And some more..."], {
+ name: "myFile"
+ });
+ formData.append('file', file);
+ var contentType = "multipart/form-data";
+ this._testAjax({url: "php/test4.php", method: "POST", postBody: formData}, null, function(inValue) {
+ var status = (inValue.ctype.indexOf(contentType) === 0) &&
+ (inValue.ctype.indexOf("boundary=--") > 10);
+ if (!status) {
+ enyo.log("Bad CT: " + inValue.ctype + " expected: " + contentType);
+ }
+ return status;
+ });
+ },
+ testXhrStatus: function() {
+ var ajax = this._testAjax({url: "php/test2.php"}, null, function(inValue) {
+ return ajax.xhr.status == 200;
+ });
+ },
+ testXhrFields: function() {
+ var ajax = this._testAjax({url: "php/test2.php", xhrFields: {withCredentials: true}}, null, function(inValue) {
+ return ajax.xhr.withCredentials;
+ });
+ },
+ // test CORS (Cross-Origin Resource Sharing) by testing against youtube api
+ testCORS: function() {
+ this._testAjax({url: "http://query.yahooapis.com/v1/public/yql/jonathan/weather/"}, {q:'select * from weather.forecast where location=94025', format: "json"}, function(inValue) {
+ return inValue && inValue.query && inValue.query.results && inValue.query.count > 0;
+ });
+ },
+ // test CORS failure
+ testCORSFailure: function() {
+ new enyo.Ajax({url: "https://dev.virtualearth.net/REST/v1/Locations/47.64054,-122.12934"})
+ .response(this, function(inSender, inValue) {
+ this.finish("CORS failure flagged as success");
+ })
+ .error(this, function(inSender, inValue) {
+ this.finish("");
+ })
+ .go();
+ },
+ // server is set to respond after 3 seconds, so make sure timeout fires first
+ testAjaxTimeout: function() {
+ new enyo.Ajax({url: "php/test3.php", timeout: 500})
+ .response(this, function(inSender, inValue) {
+ this.finish("did not timeout");
+ })
+ .error(this, function(inSender, inValue) {
+ // extra timeout is to make sure that timeout fail code cancels XHR
+ enyo.job("timeouttest", enyo.bind(this, function() {this.finish("");}), 4000);
+ })
+ .go();
+ },
+ // expected to fail
+ testErrorResponse: function() {
+ var req = this._testAjax({url: "php/test5.php"}, null, function(inValue) {
+ // getting success means server sent wrong response
+ return false;
+ }, function(inError) {
+ return (inError === 500) &&
+ req.xhrResponse &&
+ (req.xhrResponse.status === 500) &&
+ (req.xhrResponse.headers['content-type'] === "text/plain; charset=utf-8") &&
+ (req.xhrResponse.body === "my error description");
+ });
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxtestsJsonpTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/JsonpTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/JsonpTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/JsonpTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+enyo.kind({
+ name: "JsonpTest",
+ kind: enyo.TestSuite,
+ _testJsonp: function(inProps, inParams, inAssertFn) {
+ return new enyo.JsonpRequest(inProps)
+ .response(this, function(inSender, inValue) {
+ this.finish(inAssertFn.call(null, inValue) ? "" : "bad response: " + JSON.stringify(inValue));
+ })
+ .error(this, function(inSender, inValue) {
+ this.finish("bad status: " + inValue);
+ enyo.error(inValue);
+ })
+ .go(inParams);
+ },
+ _testResponse: function(inProps, inAssertFn) {
+ this._testJsonp(enyo.mixin({url: "php/test1.php?format=jsonp", callbackName: "callback"}, inProps),
+ null, inAssertFn);
+ },
+ testJsonResponse: function() {
+ this._testResponse({}, function(inValue) {
+ return inValue.response == "hello";
+ });
+ },
+ testCharset: function() {
+ this._testResponse({charset: "utf8"}, function(inValue) {
+ return inValue.utf8 == "\u0412\u0438\u0301\u0445\u0440\u0438";
+ });
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxtestsWebServiceTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/WebServiceTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/WebServiceTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/WebServiceTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,112 @@
</span><ins>+enyo.kind({
+ name: "WebServiceTest",
+ kind: enyo.TestSuite,
+ timeout: 10000,
+ _testWebService: function(inProps, inParams, inAssertFn) {
+ var ws = this.createComponent({kind: enyo.WebService, onResponse: "_response", onError: "_error", assertFn: inAssertFn}, inProps);
+ return ws.send(inParams);
+ },
+ _response: function(inSender, inValue) {
+ this.finish(inSender.assertFn(inValue.data) ? "" : "bad response: " + JSON.stringify(inValue.data));
+ },
+ _error: function(inSender, inValue) {
+ this.finish("bad status: " + inValue.data);
+ },
+ _testResponse: function(inProps, inAssertFn) {
+ this._testWebService(enyo.mixin({url: "php/test1.php?format=" + (inProps.format || inProps.handleAs)}, inProps), null, inAssertFn);
+ },
+ testJsonResponse: function() {
+ this._testResponse({handleAs: "json"},
+ function(inValue) {
+ return inValue.response == "hello";
+ }
+ );
+ },
+ testTextResponse: function() {
+ this._testResponse({handleAs: "text"}, function(inValue) {
+ return inValue == "hello";
+ });
+ },
+ testXmlResponse: function() {
+ this._testResponse({handleAs: "xml"}, function(inValue) {
+ var r = inValue.getElementsByTagName("response")[0].childNodes[0].nodeValue;
+ return r == "hello";
+ });
+ },
+ testPostRequest: function() {
+ this._testWebService({url: "php/test2.php", method: "POST"}, {query: "enyo"}, function(inValue) {
+ return inValue.response == "query.enyo";
+ });
+ },
+ testPutRequest: function() {
+ this._testWebService({url: "php/test2.php", method: "PUT"}, null, function(inValue) {
+ return inValue.status == "put";
+ });
+ },
+ testDeleteRequest: function() {
+ this._testWebService({url: "php/test2.php", method: "DELETE"}, null, function(inValue) {
+ return inValue.status == "delete";
+ });
+ },
+ testHeader: function() {
+ this._testWebService({url: "php/test2.php", method: "POST", headers: {"X-Requested-With": "XMLHttpRequest"}}, {query: "enyo"}, function(inValue) {
+ return inValue.isAjax;
+ });
+ },
+ testPostBody: function() {
+ this._testWebService({url: "php/test2.php", method: "POST", postBody: "This is a test."}, null, function(inValue) {
+ return inValue.response == "This is a test.";
+ });
+ },
+ testContentType: function() {
+ var contentType = "text/plain";
+ this._testWebService({url: "php/test2.php", method: "PUT", contentType: contentType}, null, function(inValue) {
+ return inValue.ctype == contentType;
+ });
+ },
+ testXhrStatus: function() {
+ var ajax = this._testWebService({url: "php/test2.php"}, null, function(inValue) {
+ return ajax.xhr.status == 200;
+ });
+ },
+ testXhrFields: function() {
+ var ajax = this._testWebService({url: "php/test2.php", xhrFields: {withCredentials: true}}, null, function(inValue) {
+ return ajax.xhr.withCredentials;
+ });
+ },
+ // test CORS (Cross-Origin Resource Sharing) by testing against youtube api
+ testCORS: function() {
+ this._testWebService({
+ url: "http://query.yahooapis.com/v1/public/yql/jonathan/weather/"},
+ {q: 'select * from weather.forecast where location=94025', format: "json"},
+ function(inValue) {
+ enyo.log(inValue);
+ return inValue && inValue.query && inValue.query.results && inValue.query.count > 0;
+ });
+ },
+ testJsonp: function() {
+ this._testResponse({jsonp: true, format: "jsonp"}, function(inValue) {
+ return inValue.response == "hello";
+ });
+ },
+ /*testCharset: function() {
+ this._testResponse({charset: "utf8"}, function(inValue) {
+ return inValue.utf8 == "\u0412\u0438\u0301\u0445\u0440\u0438";
+ });
+ }
+ */
+ // server is set to respond after 3 seconds, so make sure timeout fires first
+ _timeoutResponse: function(inSender, inEvent) {
+ this.finish("did not timeout");
+ },
+ _timeoutError: function(inSender, inEvent) {
+ // extra timeout is to make sure that timeout fail code cancels XHR
+ enyo.job("wstimeouttest", enyo.bind(this, function() {this.finish("");}), 4000);
+ },
+ testTimeout: function() {
+ var ws = this.createComponent({kind: enyo.WebService,
+ onResponse: "_timeoutResponse", onError: "_timeoutError"},
+ {url: "php/test3.php", timeout: 500});
+ ws.send();
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxtestsXhrTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/XhrTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/XhrTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/XhrTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+enyo.kind({
+ name: "XhrTest",
+ kind: enyo.TestSuite,
+ testXhrSync: function() {
+ var x = enyo.xhr.request({
+ url: "php/test1.php?format=text",
+ sync: true
+ });
+ if (x.responseText) {
+ this.finish("");
+ }
+ else {
+ this.finish("sync XHR didn't return with text");
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestajaxtestspackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/ajax/tests/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+enyo.depends(
+ "XhrTest.js",
+ "AjaxTest.js",
+ "JsonpTest.js",
+ "WebServiceTest.js"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoreindexhtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/index.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/index.html (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/index.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+<!doctype html>
+<html>
+ <head>
+ <title>Enyo Core Tests</title>
+ <link href="test.css" rel="stylesheet" type="text/css" />
+ <script src="../../../enyo.js" type="text/javascript"></script>
+ <script src="test.js" type="text/javascript"></script>
+ <script src="tests/package.js" type="text/javascript"></script>
+ </head>
+ <body>
+ <script type="text/javascript">
+ new enyo.TestRunner().write();
+ </script>
+ </body>
+</html>
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/test.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/test.css (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/test.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+.enyo-testcase {
+ font-family: Helvetica, Arial, sans-serif;
+ font-size: smaller;
+}
+
+.enyo-testcase-title {
+ font-weight: bold;
+ padding: 4px;
+ color: white;
+ background-color: #222;
+ text-align: center;
+}
+
+.enyo-testcase-group {
+}
+
+.enyo-testcase-running, .enyo-testcase-passed, .enyo-testcase-failed {
+ padding: 4px 4px 4px 36px;
+ border-bottom: 1px dotted gray;
+ white-space: pre;
+}
+
+.enyo-testcase-running {
+ background-color: yellow;
+}
+
+.enyo-testcase-passed {
+ background-color: #B0FFB0;
+}
+
+.enyo-testcase-failed {
+ background-color: #FF8080;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/test.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/test.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/test.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,303 @@
</span><ins>+
+// TestRunner.js
+
+/*
+To add a test case:
+ 1) Create a subclass of EnyoTestCase
+ 2) Add file to package.js
+*/
+enyo.kind({
+ name: "enyo.TestRunner",
+ kind: enyo.Control,
+ index: 0,
+ rendered: function() {
+ this.inherited(arguments);
+ this.next();
+ },
+ next: function() {
+ var test = enyo.TestSuite.tests[this.index++];
+ if (test) {
+ this.createComponent({name: test.prototype.kindName, kind: enyo.TestReporter, onFinishAll: "next"}).render().runTests();
+ }
+ }
+});
+
+// TestSuite.js
+
+/*global enyo, console
+*/
+/*
+Test Package Wish list:
+-----------------------
+Collapse success results for a suite, so large swaths of green don't hide the red.
+Expandable stack trace & logging for failures, so they can be collapsed by default.
+Support for async beforeEach & afterEach
+Jasmine style assert mechanism, so we can have fancy english text for failures
+ e.g., this.assert("spreadsheet total", total).equals(15) yields "Expected spreadsheet total 12 to equal 15"
+
+*/
+
+
+/**
+ To implement a suite of unit tests, create a subkind of enyo.TestSuite.
+ Any methods in your subkind that begin with 'test' will be invoked as unit tests when the test runner executes.
+
+ When each test is complete, it should call this.finish().
+ Pass nothing for success, or something truthy for failure (usually an explanatory message or an exception object).
+ If you do not call finish(), your test will be failed after a 3-second timeout.
+ This timeout can be customized for a given test by calling this.resetTimeout(ms).
+
+
+ See enyo-support/tests for example framework tests.
+
+*/
+enyo.kind({
+ name: "enyo.TestSuite",
+ kind: enyo.Component,
+ events: {
+ onBegin: "", // sent with test name as each test begins running.
+ onFinish: "", // sent with result as each test completes.
+ onFinishAll: "" // sent when all tests are finished.
+ },
+ timeout: 3000,
+ timeoutMessage: "timed out",
+ /** @public
+ Replaces the current test timeout with
+ May be called by individual tests to reset/lengthen/shorten the test timeout.
+ Mostly good for unusually long-running tests, but can be used for shortening the timeout duration, or
+ even for setting different timeouts for successive stages of a test.
+ */
+ resetTimeout: function(timeout) {
+ this.clearTimer();
+ this.timer = window.setTimeout(enyo.bind(this, "timedout"), timeout || this.timeout);
+ },
+ /** @public
+ Tests can call this.log() to print useful diagnostic information.
+ The logs are accumulated, and only displayed when the test fails.
+ Logged objects will be automatically converted to JSON.
+ */
+ log: function(msg) {
+ this.logMessages = this.logMessages || [];
+ if (typeof msg !== "string") {
+ msg = JSON.stringify(msg);
+ }
+ this.logMessages.push(msg);
+ },
+ // Subclasses can override this method.
+ // It will be called before each test executes.
+ // It can be used to run common setup code.
+ beforeEach: function() {
+ },
+ // Subclasses can override this method.
+ // It will be called exactly once as each test finishes, even in failure cases.
+ // It can be used to reliably execute cleanup code.
+ afterEach: function() {
+ },
+ // Runs all the tests in the suite.
+ // This component can operate in a couple of modes... one where it runs all tests, and one where it runs only a single test.
+ // When running all tests, it allocates a fresh child component for each test, and then uses that to do actually run the test,
+ // passing along any relevant events to our owner. The reason for this is to eliminate unintentional state sharing between tests,
+ // and to make sure that lingering test code that calls finish() at a later time does not affect the state of a different test.
+ runAllTests: function() {
+ if (this.autoRunNextTest) {
+ console.error("TestSuite.runAllTests: Already running.");
+ return; // already running.
+ }
+ this.testNames = this.getTestNames();
+ this.index = 0;
+ this.autoRunNextTest = true;
+ this.next();
+ },
+ getTestNames: function() {
+ // NOTE: name no function or property test* before this point unless it's really a test
+ var names = [];
+ for (var key in this) {
+ if (/^test/.test(key)) {
+ names.push(key);
+ }
+ }
+ return names;
+ },
+ next: function() {
+ var testName;
+ if (!this.autoRunNextTest) {
+ return;
+ }
+ testName = this.testNames[this.index++];
+ this.current = testName;
+ if (testName) {
+ // Allocate a new child component to run the test.
+ if (this.$[testName]) {
+ this.$[testName].destroy();
+ }
+ this.createComponent({name: testName, kind:this.kind, onBegin: "childTestBegun", onFinish: "childTestFinished"});
+ this.$[testName].runTest(testName);
+ } else {
+ this.autoRunNextTest = false;
+ this.doFinishAll();
+ }
+ },
+ // Called on a component running in the "run a single test" mode to run the actual test.
+ runTest: function(inTestName) {
+ this.resetTimeout();
+ this.doBegin({testName: inTestName});
+ try {
+ // actual test code invoked here
+ this.beforeEach();
+ this[inTestName]();
+ } catch(x) {
+ this.finish(x);
+ }
+ },
+ timedout: function() {
+ this.finish(this.timeoutMessage);
+ },
+ clearTimer: function() {
+ window.clearTimeout(this.timer);
+ },
+ // Call finish() to indicate success, or finish("<reason-message>") to indicate failure.
+ finish: function(inMessage) {
+ enyo.asyncMethod(this, "reallyFinish", inMessage);
+ },
+ reallyFinish: function(inMessage) {
+ // If finish has been called before, then we ignore it
+ // unless we passed previously and now we're failing.
+ // We will send multiple finish events if we get a success and then a failure -- that counts as a failure.
+ if (this.results) {
+ console.warn("Finish called more than once in test "+this.name);
+ if (!this.results.passed || !inMessage) {
+ return;
+ }
+ }
+ this.results = {
+ suite: this.kindName,
+ name: this.name,
+ passed: !inMessage,
+ logs: this.logMessages
+ };
+ if (inMessage) {
+ if ((typeof inMessage) === "string") { // In message could be a string...
+ this.results.message = inMessage;
+ } else if (inMessage.message !== undefined) { // ... or an exception ...
+ this.results.message = inMessage.message;
+ this.results.exception = inMessage;
+ } else { // ... or some other object ...
+ this.results.message = inMessage.errorText || inMessage.toString();
+ this.results.failValue = inMessage;
+ }
+ // Except for timeouts, make sure we have an exception so we can get a backtrace.
+ if (!this.results.exception && inMessage !== this.timeoutMessage) {
+ try {
+ throw new Error(inMessage);
+ } catch(e) {
+ this.results.exception = e;
+ }
+ }
+ }
+ this.clearTimer();
+ // Execute afterEach method, if we haven't already.
+ if (this.afterEach) {
+ try {
+ this.afterEach();
+ } catch(x) {
+ this.afterEach = null; // so we don't try again when we recurse.
+ this.finish(x); // we count an afterEach exception as a failure, even if the test result was originally success.
+ }
+ this.afterEach = null; // so we don't try again
+ }
+ this.doFinish({results: this.results}); // bubble results
+ },
+ childTestBegun: function(inSender) {
+ // Pass child test begin event up, with the test name.
+ // This can be used to trigger UI.
+ this.triggeredNextTest = false;
+ },
+ childTestFinished: function(inSender, inResults) {
+ // We do not destroy the child component yet, in case it calls finish() again later with a failure... in that case, we still fail it.
+ if (!this.triggeredNextTest) {
+ this.triggeredNextTest = true;
+ enyo.asyncMethod(this, "next");
+ }
+ }
+
+});
+
+enyo.TestSuite.tests = [];
+
+enyo.TestSuite.subclass = function(ctor, props) {
+ // make a list of TestSuite subclasses so we can run them automatically
+ // if one needs to make a TestSuite subclass that isn't actually a TestSuite itself,
+ // they should assign a truthy 'testBase' property
+ if (!props.testBase) {
+ enyo.TestSuite.tests.push(ctor);
+ }
+};
+
+// TestReporter.js
+
+// UI kind responsible for creating test component, running tests, receiving & displaying test results.
+enyo.kind({
+ name: "enyo.TestReporter",
+ kind: enyo.Control,
+ published: {
+ results: null
+ },
+ events: {
+ onFinishAll: ""
+ },
+ components: [
+ {name: "title", classes: "enyo-testcase-title"},
+ {name: "group", classes: "enyo-testcase-group"}
+ ],
+ classes: "enyo-testcase",
+ timeout: 3000,
+ create: function() {
+ this.inherited(arguments);
+ this.$.title.setContent(this.name);
+ },
+ initComponents: function() {
+ this.inherited(arguments);
+ this.createComponent({name: "testSuite", kind: this.name, onBegin: "testBegun", onFinish: "updateTestDisplay"});
+ },
+ runTests: function() {
+ this.$.testSuite.runAllTests();
+ },
+ testBegun: function(inSender, inEvent) {
+ this.$.group.createComponent({name: inEvent.testName, classes: "enyo-testcase-running", content: inEvent.testName + ": running", allowHtml: true}).render();
+ },
+ formatStackTrace: function(inStack) {
+ var stack = inStack.split("\n");
+ var out = [''];
+ for (var i=0, s; s=stack[i]; i++) {
+ if (s.indexOf(" at Object.do") == 0 || s.indexOf(" at Object.dispatch") == 0 || s.indexOf("TestSuite.js") != -1) {
+ continue;
+ }
+ out.push(s);
+ }
+ return out.join("<br/>");
+ },
+ updateTestDisplay: function(inSender, inEvent) {
+ var results = inEvent.results;
+ var e = results.exception;
+ var info = this.$.group.$[results.name];
+ var content = "<b>" + results.name + "</b>: " + (results.passed ? "PASSED" : results.message);
+ if (e) {
+ // If we have an exception include the stack trace or file/line number.
+ if (e.stack) {
+ content += this.formatStackTrace(e.stack);
+ } else if (e.sourceURL && e.line) {
+ content += "<br/>" + e.sourceURL + ":" + e.line;
+ }
+ // if fail was called with an object, show the JSON. This is likely a service request error or somesuch.
+ if (results.failValue) {
+ content += "<br/>" + enyo.json.stringify(results.failValue).replace(/\\n/g, "<br/>");
+ }
+ }
+ // Show logs if we have any.
+ if (!results.passed && results.logs) {
+ content += "<br/>" + results.logs.join("<br/>");
+ }
+ info.setContent(content);
+ info.setClasses("enyo-testcase-" + (results.passed ? "passed" : "failed"));
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsAjaxTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/AjaxTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/AjaxTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/AjaxTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+enyo.kind({
+ name: "AjaxTest",
+ kind: enyo.TestSuite,
+ testAjax200: function() {
+ new enyo.Ajax({url: "index.html", handleAs: "text"})
+ .response(this, function(inSender, inValue){
+ this.finish();
+ })
+ .error(this, function(inSender, inValue) {
+ this.finish("bad status: " + inValue);
+ })
+ .go();
+ },
+ testAjax404: function() {
+ new enyo.Ajax({url: "noexist.not"})
+ .response(this, function(inSender, inValue){
+ this.finish("ajax failed to fail");
+ })
+ .error(this, function(inSender, inValue) {
+ this.finish();
+ })
+ .go();
+ },
+ testAjaxCustomError: function() {
+ new enyo.Ajax({url: "appinfo.json"})
+ .response(function(inSender, inValue){
+ inSender.fail("cuz I said so");
+ })
+ .error(this, function(inSender, inValue) {
+ this.finish();
+ })
+ .go();
+ },
+ testAjaxSerial: function() {
+ // if the test finishes before ready, it's a failure
+ var ready = false;
+ //
+ // when 'index' request completes, we are 'ready'
+ var index = new enyo.Ajax({url: "index.html", handleAs: "text"});
+ index.response(function() {
+ ready = true;
+ });
+ //
+ // request triggers 'index' request when it completes
+ new enyo.Ajax({url: "index.html", handleAs: "text"})
+ .response(index)
+ .response(this, function() {
+ // finish clean if 'ready'
+ this.finish(ready ? "" : "requests failed to complete in order");
+ })
+ .go();
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsAsyncTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/AsyncTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/AsyncTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/AsyncTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+enyo.kind({
+ name: "AsyncTest",
+ kind: enyo.TestSuite,
+ testAsyncExists: function() {
+ new enyo.Async();
+ this.finish();
+ },
+ testAsyncFail: function() {
+ var a = new enyo.Async();
+ a.response(this, function(inSender, inValue) {
+ this.finish("error response not passed to success handler");
+ });
+ a.error(this, function() {
+ this.finish();
+ });
+ a.fail("foo");
+ },
+ testAsyncInnerFail: function() {
+ new enyo.Async()
+ .response(function(inSender, inValue) {
+ inSender.fail("always fail");
+ })
+ .error(this, function() {
+ this.finish();
+ })
+ .respond("foo")
+ ;
+ },
+ testAsyncInnerFailRecover: function() {
+ new enyo.Async()
+ .response(function(inSender, inValue) {
+ inSender.fail("first response always fails");
+ })
+ .error(function(inSender) {
+ inSender.recover();
+ return "recovery response";
+ })
+ .response(this, function(inSender, inValue) {
+ this.finish(inValue == "recovery response" ? null : "fail");
+ })
+ .respond("foo")
+ ;
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsComponentDispatchTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ComponentDispatchTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ComponentDispatchTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ComponentDispatchTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+enyo.kind({
+ name: "ComponentDispatchTest",
+ kind: enyo.TestSuite,
+ testDispatchEvent2NullArgs: function() {
+ var test = this;
+ var c = new enyo.Component({
+ handlers: {
+ onOk: "ok"
+ },
+ ok: function(inSender, inEvent) {
+ test.finish((inSender != c && "bad inSender") || (arguments.length !== 2 && "bad arguments"));
+ }
+ });
+ c.dispatchEvent("onOk");
+ },
+ testDispatchEvent2OneArg: function() {
+ var test = this;
+ var c = new enyo.Component({
+ handlers: {
+ onOk: "ok"
+ },
+ ok: function(inSender, inEvent) {
+ test.finish((inSender != c && "bad inSender") || (inEvent.value !== 42 && "bad inValue"));
+ }
+ });
+ c.dispatchEvent("onOk", {value: 42});
+ },
+ testDispatchEvent2Owner: function() {
+ var test = this;
+ var c = new enyo.Component({
+ components: [{
+ name: "child",
+ onOk: "ok"
+ }],
+ ok: function(inSender, inEvent) {
+ test.finish((inSender != this.$.child && "bad inSender") || (inEvent.value !== 42 && "bad inValue"));
+ }
+ });
+ c.$.child.dispatchEvent("onOk", {value: 42});
+ },
+ testBubble: function() {
+ var test = this;
+ var c = new enyo.Component({
+ components: [{
+ name: "child"
+ }],
+ handlers: {
+ onOk: "ok"
+ },
+ ok: function(inSender, inEvent) {
+ test.finish((inSender != c.$.child && "bad inSender") || (inEvent.value !== 42 && "bad inValue"));
+ }
+ });
+ c.$.child.bubble("onOk", {value: 42});
+ },
+ testDoubleBubble: function() {
+ var test = this;
+ var owner = new enyo.Component({
+ handlers: {
+ onOk: "ok"
+ },
+ ok: function(inSender, inEvent) {
+ test.finish((inSender != child && "bad inSender") || (inEvent.value !== 42 && "bad inValue"));
+ }
+ });
+ var child = new enyo.Component({
+ owner: owner
+ });
+ var grandchild = new enyo.Component({
+ owner: child
+ });
+ grandchild.bubble("onOk", {value: 42});
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsComponentHandlersTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ComponentHandlersTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ComponentHandlersTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ComponentHandlersTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+enyo.kind({
+ name: "ComponentHandlersTest",
+ kind: enyo.TestSuite,
+ testHandlerUnion: function() {
+ enyo.kind({
+ name: "TestBase",
+ kind: enyo.Component,
+ handlers: {
+ onOk: "ok"
+ }
+ });
+ enyo.kind({
+ name: "TestSub",
+ kind: TestBase,
+ handlers: {
+ onMore: "more"
+ }
+ });
+ var h = new TestSub({handlers: {onFurther: "foo"}}).handlers;
+ this.finish((!h.onOk && "bad onOk") || (!h.onMore && "bad onMore") || (!h.onFurther && "bad onFurther"));
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsComponentTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ComponentTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ComponentTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ComponentTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+enyo.kind({
+ name: "ComponentTest",
+ kind: enyo.TestSuite,
+ testNestedComponentUndefinedKind: function() {
+ var pass = false;
+ // should throw exception as this is an error
+ try {
+ var a = enyo.kind(
+ {
+ name: "parentComponent",
+ components: [
+ {
+ name: "nestedComponent",
+ kind: undefined
+ }
+ ]
+ }
+ );
+ new a({});
+ } catch(e) {
+ pass = true;
+ }
+ if (!pass) {
+ throw("no exception for explicitly undefined kind in a nested component");
+ }
+ this.finish();
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsControlPropsTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ControlPropsTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ControlPropsTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ControlPropsTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+enyo.kind({
+ name: "ControlPropsTest",
+ kind: enyo.TestSuite,
+ testUnionAttributesStylesClasses: function() {
+ enyo.kind({
+ name: "TestBase",
+ kind: enyo.Control,
+ attributes: {
+ a: 1
+ },
+ style: "a:1",
+ classes: "a"
+ });
+ enyo.kind({
+ name: "TestSub",
+ kind: TestBase,
+ attributes: {
+ b: 1
+ },
+ style: "b:1",
+ classes: "b"
+ });
+ var t = new TestSub({attributes: {c: 1}, style: "c:1", classes: "c"});
+ this.finish(
+ (!t.attributes.a && "bad a attr") || (!t.attributes.b && "bad b attr") || (!t.attributes.c && "bad c attr")
+ ||
+ (!t.domStyles.a && "bad a style") || (!t.domStyles.b && "bad b style") /*|| (!t.domStyles.c && "bad c style")*/
+ ||
+ (t.attributes['class'] !== "a b c" && "bad classes, expected [a b c] got [" + t.attributes['class'] + "]")
+ );
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsControlTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ControlTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ControlTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ControlTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,92 @@
</span><ins>+enyo.kind({
+ name: "ControlTest",
+ kind: enyo.TestSuite,
+ testAddingComponents: function() {
+ var K = enyo.kind({
+ kind: enyo.Control,
+ components: [
+ { name: "a" },
+ { name: "b" },
+ { name: "c" }
+ ]
+ });
+
+ // create new div, attach to start of body, delete at end
+ // needed because we need live DOM with getElementById working
+ var div = document.createElement("div");
+ document.body.appendChild(div);
+
+ var k = new K();
+ k.renderInto(div);
+
+ var kn = div.firstChild;
+ try {
+ // basic tests of rendered nodes
+ if (k.hasNode() !== kn) {
+ throw("control node doesn't match rendering");
+ }
+ if (kn.firstChild !== k.$.a.hasNode()) {
+ throw("a child not first node");
+ }
+ if (kn.lastChild !== k.$.c.hasNode()) {
+ throw("c child not last node");
+ }
+ // test deleting c
+ k.$.c.destroy();
+ if (kn.lastChild !== k.$.b.hasNode()) {
+ throw("b child not last node after deletion");
+ }
+ // add new node to end
+ var cc = k.createComponent({});
+ cc.render();
+ if (kn.lastChild !== cc.hasNode()) {
+ throw("added a child to end, not last node");
+ }
+ // add new node before a (should be at start)
+ var aa = k.createComponent({}, {addBefore: k.$.a});
+ aa.render();
+ if (kn.firstChild !== aa.hasNode()) {
+ throw("added a child using node reference, not first node");
+ }
+ // add another node to start using addBefore: null
+ var aaa = k.createComponent({}, {addBefore: null});
+ aaa.render();
+ if (kn.firstChild !== aaa.hasNode()) {
+ throw("added a child not first node");
+ }
+ } finally {
+ // clean up after our test
+ k.destroy();
+ document.body.removeChild(div);
+ }
+ this.finish();
+ },
+ testGetBounds: function() {
+ var K = enyo.kind({
+ style: "position: absolute; top: 10px; height: 30px; left: 15px; width: 35px;"
+ });
+ // create new div, attach to start of body, delete at end
+ // needed because we need live DOM with getElementById working
+ var div = document.createElement("div");
+ document.body.appendChild(div);
+
+ var k = new K();
+ var b;
+ b = k.getBounds();
+ if (b.top !== undefined || b.left !== undefined || b.height !== undefined || b.width !== undefined) {
+ throw("bad bounds, expected all undefined, got " + JSON.stringify(b));
+ }
+ k.renderInto(div);
+ try {
+ b = k.getBounds();
+ if (b.top !== 10 || b.left !== 15 || b.height !== 30 || b.width !== 35) {
+ throw("bad bounds, expected {top: 10, left: 15, height: 30, width: 35}, got " + JSON.stringify(b));
+ }
+ } finally {
+ // clean up after our test
+ k.destroy();
+ document.body.removeChild(div);
+ }
+ this.finish();
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsDecodePackagePathTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/DecodePackagePathTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/DecodePackagePathTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/DecodePackagePathTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,70 @@
</span><ins>+enyo.kind({
+ name: "DecodePackagePathTest",
+ kind: enyo.TestSuite,
+ assert: function(inParts, inPart, inValue) {
+ if (inParts[inPart] != inValue) {
+ this.finish('bad ' + inPart + ', expected "' + inValue + '" got "' + inParts[inPart] + '"');
+ return false;
+ }
+ return true;
+ },
+ decodeTest: function(inPath, inExpected) {
+ var parts = enyo.loaderFactory.prototype.decodePackagePath(inPath);
+ for (var n in inExpected) {
+ if (!this.assert(parts, n, inExpected[n])) {
+ return;
+ }
+ }
+ this.finish();
+ },
+ testDecodeEmpty: function() {
+ this.decodeTest("", {folder: "", manifest: "package.js", alias: "", target: ""});
+ },
+ testDecodeFoo: function() {
+ this.decodeTest("foo", {folder: "foo/", manifest: "foo/package.js", alias: "foo", target: "foo"});
+ },
+ testDecodeFooSlash: function() {
+ this.decodeTest("foo/", {folder: "foo/", manifest: "foo/package.js", alias: "foo", target: "foo"});
+ },
+ testDecodeFooBackSlash: function() {
+ this.decodeTest("foo\\", {folder: "foo/", manifest: "foo/package.js", alias: "foo", target: "foo"});
+ },
+ testDecodeFooBarBaz: function() {
+ this.decodeTest("foo/bar/baz", {folder: "foo/bar/baz/", manifest: "foo/bar/baz/package.js", alias: "foo-bar-baz", target: "foo/bar/baz"});
+ },
+ testDecodeParentFoo: function() {
+ this.decodeTest("../foo", {folder: "../foo/", manifest: "../foo/package.js", alias: "foo", target: "../foo"});
+ },
+ testDecodeFooBarLibBaz: function() {
+ this.decodeTest("foo/bar/lib/baz", {folder: "foo/bar/lib/baz/", manifest: "foo/bar/lib/baz/package.js", alias: "baz", target: "foo/bar/lib/baz"});
+ },
+ testDecodeEnyoFoo: function() {
+ var $enyo = enyo.path.rewrite("$enyo");
+ this.decodeTest($enyo + "/foo", {folder: $enyo + "foo/", manifest: $enyo + "foo/package.js", alias: "foo", target: $enyo + "foo"});
+ },
+ testDecodeAbsEnyoFoo: function() {
+ var $enyo = enyo.path.rewrite("$enyo") + "../enyo/";
+ this.decodeTest($enyo + "foo", {folder: $enyo + "foo/", manifest: $enyo + "foo/package.js", alias: "foo", target: $enyo + "foo"});
+ },
+ testDecodeSource: function() {
+ this.decodeTest("source", {folder: "source/", manifest: "source/package.js", alias: "", target: ""});
+ },
+ testDecodeFooBarSource: function() {
+ this.decodeTest("foo/bar/source", {folder: "foo/bar/source/", manifest: "foo/bar/source/package.js", alias: "foo-bar", target: "foo/bar"});
+ },
+ testDecodeFooBarSourceZot: function() {
+ this.decodeTest("foo/bar/source/zot", {folder: "foo/bar/source/zot/", manifest: "foo/bar/source/zot/package.js", alias: "foo-bar-zot", target: "foo/bar/zot"});
+ },
+ testDecodeSourceFoo: function() {
+ this.decodeTest("source/foo", {folder: "source/foo/", manifest: "source/foo/package.js", alias: "foo", target: "foo"});
+ },
+ testLocalPackage: function() {
+ this.decodeTest("package.js", {folder: "", manifest: "package.js", alias: "", target: ""});
+ },
+ testFooPackage: function() {
+ this.decodeTest("foo/package.js", {folder: "foo/", manifest: "foo/package.js", alias: "foo", target: "foo"});
+ },
+ testRemote: function() {
+ this.decodeTest("http://flarn.com/lib/foo", {folder: "http://flarn.com/lib/foo/", manifest: "http://flarn.com/lib/foo/package.js", alias: "foo", target: "http://flarn.com/lib/foo"});
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsJsonTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/JsonTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/JsonTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/JsonTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+enyo.kind({
+ name: "JSONTest",
+ kind: enyo.TestSuite,
+ testJsonStringifyExists: function() {
+ enyo.json.stringify();
+ this.finish();
+ },
+ testJsonParseExists: function() {
+ enyo.json.parse();
+ this.finish();
+ },
+ testJsonParseSimple: function() {
+ var obj = enyo.json.parse('{"foo":"bar"}'), err;
+ if (!obj.foo || obj.foo !== "bar") {
+ err = "JSON string did not parse correctly";
+ }
+ this.finish(err);
+ },
+ testJsonParseReviver: function() {
+ var dates = '{"hired":"2012-01-01T12:00:00Z","fired":"2012-01-02T12:00:00Z"}',
+ parsed = enyo.json.parse(dates, function(key, value) {
+ var a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+ if ( a ) {
+ return new Date(
+ Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6])
+ );
+ }
+ return value;
+ }),
+ err;
+ if (!(parsed.hired instanceof Date)) {
+ err = "JSON string did not parse and revive correctly";
+ }
+ this.finish(err);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsKindTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/KindTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/KindTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/KindTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+enyo.kind({
+ name: "KindTest",
+ kind: enyo.TestSuite,
+ testNamespace: function() {
+ enyo.kind({name: "custom.Namespace"});
+ Boolean(custom.Namespace); // throws an exception if namespace is undefined (Boolean() is just for lint)
+ this.finish();
+ },
+ testNullKind: function() {
+ // should succeed as this is allowed
+ var K = enyo.kind({kind: null});
+ var i = new K({});
+ this.finish();
+ },
+ testUndefinedKind: function() {
+ // should throw exception as this is an error
+ var pass = false;
+ try {
+ enyo.kind({kind: undefined});
+ } catch(e) {
+ pass = true;
+ }
+ if (!pass) {
+ throw("no exception for explicitly undefined kind");
+ }
+ this.finish();
+ },
+ testBadStringKind: function() {
+ // should throw exception as this is an error
+ var pass = false;
+ try {
+ enyo.kind({kind: "FooBarBaz"});
+ } catch(e) {
+ pass = true;
+ }
+ if (!pass) {
+ throw("no exception for misnamed kind");
+ }
+ this.finish();
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsLoaderTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/LoaderTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/LoaderTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/LoaderTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+enyo.kind({
+ name: "LoaderTest",
+ kind: enyo.TestSuite,
+ testSingleLoad: function() {
+ enyo.load("tests/loader1.js", enyo.bind(this,
+ function() {
+ if (window.LOADER_TEST === "loader1") {
+ this.finish();
+ }
+ else {
+ this.finish("callback called before load complete");
+ }
+ }
+ ));
+ },
+ testMultipleLoad: function() {
+ enyo.load(["tests/loader2a.js", "tests/loader2b.js"],
+ enyo.bind(this, function() {
+ if (window.LOADER_TEST === "loader2b") {
+ this.finish();
+ }
+ else {
+ this.finish("callback called before load complete");
+ }
+ }
+ ));
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsPathResolverTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/PathResolverTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/PathResolverTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/PathResolverTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+enyo.kind({
+ name: "PathResolverTest",
+ kind: enyo.TestSuite,
+ rewriteTest: function(inResolver, inPath, inExpected) {
+ var pf= enyo.loader.packageFolder;
+ enyo.loader.packageFolder = "./source/";
+
+ var result = enyo.loader.getPathPrefix(inPath) + inResolver.rewrite(inPath);
+
+ if (result === inExpected) {
+ this.finish();
+ } else {
+ this.finish("Expected: '" + inExpected + "' Got: '" + result + "'");
+ }
+
+ enyo.loader.packageFolder = pf;
+ },
+ testNormalPath: function() {
+ var resolver = new enyo.pathResolverFactory();
+ this.rewriteTest(resolver, "my/folder", "./source/my/folder");
+ },
+ testLeadingSlashPath: function() {
+ var resolver = new enyo.pathResolverFactory();
+ this.rewriteTest(resolver, "/my/folder", "/my/folder");
+ },
+ testRewriteHttps: function() {
+ var resolver = new enyo.pathResolverFactory();
+ this.rewriteTest(resolver, "https://my.server/file.js", "https://my.server/file.js");
+ },
+ testRewriteHttpMixedCase: function() {
+ var resolver = new enyo.pathResolverFactory();
+ this.rewriteTest(resolver, "hTtP://my.server/file.js", "hTtP://my.server/file.js");
+ },
+ testRewriteUnknown: function() {
+ var resolver = new enyo.pathResolverFactory();
+ this.rewriteTest(resolver, "$enyo/package.js", "package.js");
+ },
+ testRewriteEnyo: function() {
+ var resolver = new enyo.pathResolverFactory();
+ resolver.addPaths({enyo: "my-enyo-dir", lib: "$enyo/../lib"});
+ this.rewriteTest(resolver, "$enyo/package.js", "my-enyo-dir/package.js");
+ },
+ testRewriteOnyx: function() {
+ var resolver = new enyo.pathResolverFactory();
+ resolver.addPaths({enyo: "my-enyo-dir", lib: "$enyo/../lib"});
+ this.rewriteTest(resolver, "$lib/onyx", "my-enyo-dir/../lib/onyx");
+ },
+ testRewriteEnyoPath: function() {
+ var input = "$lib/onyx";
+ var result = enyo.path.rewrite(input);
+ if (result !== "onyx" && result != input) {
+ this.finish();
+ } else {
+ this.finish("Got: '" + result + "'");
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsViewportPositioningTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ViewportPositioningTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ViewportPositioningTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/ViewportPositioningTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,104 @@
</span><ins>+enyo.kind({
+ name: "ViewportPositioningTest",
+ kind: enyo.TestSuite,
+
+ testMeasuringViewportCoordinates: function() {
+ var K = enyo.kind({
+ kind: enyo.Control,
+ style: "position: absolute; top: 10px; left: 10px; width: 10px; height: 10px;"
+ });
+
+ // Similar to ControlTest, create a testing div to test DOM information with (delete at end)
+ var div = document.createElement("div");
+ document.body.appendChild(div);
+ // Apply fixed positioning so that we know where things should be relative to the viewport
+ div.style.position = 'fixed';
+ div.style.top = '0px';
+ div.style.left = '0px';
+ div.style.width = '100%';
+ div.style.height = '100%';
+ div.style.boxSizing = 'border-box';
+
+ var k = new K();
+ k.renderInto(div);
+
+ var p = enyo.dom.calcNodePosition(k.hasNode()),
+ // Bottom and right require calculating viewport size
+ fromBottom = (document.body.parentNode.offsetHeight > enyo.dom.getWindowHeight() ? enyo.dom.getWindowHeight() - document.body.parentNode.scrollTop : document.body.parentNode.offsetHeight) - 20,
+ fromRight = (document.body.parentNode.offsetWidth > enyo.dom.getWindowWidth() ? enyo.dom.getWindowWidth() - document.body.parentNode.scrollLeft : document.body.parentNode.offsetWidth) - 20;
+ if (p.top !== 10) {
+ this.log('top failed with value: ' + p.top + ' (should be 10)');
+ }
+ if (p.left !== 10) {
+ this.log('left failed with value: ' + p.left + ' (should be 10)');
+ }
+ if (p.bottom !== fromBottom) {
+ this.log('bottom failed with value: ' + p.bottom + ' (should be ' + fromBottom + ')');
+ }
+ if (p.right !== fromRight) {
+ this.log('right failed with value: ' + p.right + ' (should be ' + fromRight + ')');
+ }
+ if (p.width !== 10) {
+ this.log('width failed with value: ' + p.width + ' (should be 10)');
+ }
+ if (p.height !== 10) {
+ this.log('height failed with value: ' + p.height + ' (should be 10)');
+ }
+
+ // Now test measuring the element when a parent has a border
+ div.style.border = "1px solid transparent";
+ k.hasNode().style.border = "1px solid transparent";
+ p = enyo.dom.calcNodePosition(k.hasNode()),
+ // We don't count the right border on the element itself because that is taken into account automatically by the element's width measurement
+ fromBottom -= 3,
+ fromRight -= 3;
+ if (p.top !== 11) {
+ this.log('top with border failed with value: ' + p.top + ' (should be 11)');
+ }
+ if (p.left !== 11) {
+ this.log('left with border failed with value: ' + p.left + ' (should be 11)');
+ }
+ if (p.bottom !== fromBottom) {
+ this.log('bottom with border failed with value: ' + p.bottom + ' (should be ' + fromBottom + ')');
+ }
+ if (p.right !== fromRight) {
+ this.log('right with border failed with value: ' + p.right + ' (should be ' + fromRight + ')');
+ }
+ if (p.width !== 12) {
+ this.log('width with border failed with value: ' + p.width + ' (should be 12)');
+ }
+ if (p.height !== 12) {
+ this.log('height with border failed with value: ' + p.height + ' (should be 12)');
+ }
+
+ // And finally, test positioning relative to another node
+ p = enyo.dom.calcNodePosition(k.hasNode(), div),
+ // Reset to div size - node height
+ fromBottom = div.offsetHeight - 22,
+ fromRight = div.offsetWidth - 22;
+ if (p.top !== 10) {
+ this.log('top relative to div failed with value: ' + p.top + ' (should be 10)');
+ }
+ if (p.left !== 10) {
+ this.log('left relative to div failed with value: ' + p.left + ' (should be 10)');
+ }
+ if (p.bottom !== fromBottom) {
+ this.log('bottom relative to div failed with value: ' + p.bottom + ' (should be ' + fromBottom + ')');
+ }
+ if (p.right !== fromRight) {
+ this.log('right relative to div failed with value: ' + p.right + ' (should be ' + fromRight + ')');
+ }
+ if (p.width !== 12) {
+ this.log('width relative to div failed with value: ' + p.width + ' (should be 12)');
+ }
+ if (p.height !== 12) {
+ this.log('height relative to div failed with value: ' + p.height + ' (should be 12)');
+ }
+
+ // Clean up
+ k.destroy();
+ document.body.removeChild(div);
+
+ this.finish(this.logMessages && this.logMessages.length ? 'Following measurements failed:' : '');
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestslangTestjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/langTest.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/langTest.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/langTest.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+enyo.kind({
+ name: "langTest",
+ kind: enyo.TestSuite,
+ testCallee: function() {
+ var err = "";
+ var fn = function() {
+ err = (arguments.callee.nom !== 'fn');
+ };
+ fn.nom = "fn";
+ fn();
+ this.finish(err);
+ },
+ testClass: function() {
+ enyo.kind({
+ name: "AClass"
+ });
+ var obj = new AClass();
+ var err = (typeof AClass !== 'function');
+ this.finish(err);
+ },
+ testisString: function() {
+
+ // Create alternate window context to write vars from
+ var iframe = document.createElement("iframe"),
+ iframeDoc, err;
+
+ document.body.appendChild(iframe);
+ iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
+ iframeDoc.write("<script>parent.iString = new String('hello');</script>");
+ iframeDoc.close();
+
+ if (!enyo.isString("string")) {
+ err = "enyo.isString() cannot determine strings correctly";
+ }
+ // This will fail:
+ // - instanceof from another context
+ // - typeof (b/c it is a string instance)
+ // https://github.com/enyojs/enyo/issues/2
+ if (!enyo.isString(iString)) {
+ err = "enyo.isString() cannot determine strings written from other window contexts correctly";
+ }
+
+ document.body.removeChild(iframe);
+ this.finish(err);
+ },
+ testindexOfRegular: function() {
+ var index = enyo.indexOf("foo", [null, null, null, null,"foo"]);
+ this.finish(index !== 4 ? "Incorrect index" : false);
+ },
+ testindexOfFromIndex: function() {
+ var index = enyo.indexOf("foo", [null, null, null, null,"foo"], 10);
+ this.finish(index !== -1 ? "if fromIndex is greater then array length, should return -1" : false);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsloader1js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/loader1.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/loader1.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/loader1.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+window.LOADER_TEST = "loader1";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsloader2ajs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/loader2a.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/loader2a.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/loader2a.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+window.LOADER_TEST = "loader2a";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestsloader2bjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/loader2b.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/loader2b.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/loader2b.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+window.LOADER_TEST = "loader2b";
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkenyotoolstestcoretestspackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/enyo/tools/test/core/tests/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+enyo.depends(
+ "langTest.js",
+ //"LoaderTest.js",
+ "KindTest.js",
+ "JsonTest.js",
+ "AsyncTest.js",
+ "AjaxTest.js",
+ "ComponentTest.js",
+ "ComponentDispatchTest.js",
+ "ComponentHandlersTest.js",
+ "ControlTest.js",
+ "ControlPropsTest.js",
+ "DecodePackagePathTest.js",
+ "PathResolverTest.js",
+ "ViewportPositioningTest.js"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkiconpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/icon.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/icon.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/icon.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/icon.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/icon.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagescomposeicon_bquotepng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/compose/icon_bquote.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/compose/icon_bquote.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/compose/icon_bquote.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/compose/icon_bquote.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/compose/icon_bquote.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagescomposeicon_camerapng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/compose/icon_camera.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/compose/icon_camera.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/compose/icon_camera.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/compose/icon_camera.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/compose/icon_camera.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagescomposeicon_centerpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/compose/icon_center.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/compose/icon_center.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/compose/icon_center.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/compose/icon_center.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/compose/icon_center.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagescomposeicon_leftpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/compose/icon_left.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/compose/icon_left.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/compose/icon_left.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/compose/icon_left.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/compose/icon_left.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagescomposeicon_linkpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/compose/icon_link.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/compose/icon_link.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/compose/icon_link.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/compose/icon_link.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/compose/icon_link.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagescomposeicon_morepng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/compose/icon_more.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/compose/icon_more.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/compose/icon_more.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/compose/icon_more.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/compose/icon_more.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagescomposeicon_olpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/compose/icon_ol.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/compose/icon_ol.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/compose/icon_ol.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/compose/icon_ol.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/compose/icon_ol.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagescomposeicon_rightpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/compose/icon_right.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/compose/icon_right.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/compose/icon_right.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/compose/icon_right.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/compose/icon_right.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagescomposeicon_ulpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/compose/icon_ul.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/compose/icon_ul.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/compose/icon_ul.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/compose/icon_ul.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/compose/icon_ul.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagesfaviconpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/favicon.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/favicon.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/favicon.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/favicon.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/favicon.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagesicon128png"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/icon128.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/icon128.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/icon128.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/icon128.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/icon128.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagesicon30png"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/icon30.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/icon30.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/icon30.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/icon30.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/icon30.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagesicon48png"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/icon48.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/icon48.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/icon48.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/icon48.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/icon48.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagesicon60png"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/icon60.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/icon60.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/icon60.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/icon60.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/icon60.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagesicon64png"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/icon64.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/icon64.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/icon64.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/icon64.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/icon64.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagestoolbarbackpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/toolbar/back.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/toolbar/back.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/toolbar/back.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/toolbar/back.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/toolbar/back.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagestoolbardrawerpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/toolbar/drawer.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/toolbar/drawer.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/toolbar/drawer.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/toolbar/drawer.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/toolbar/drawer.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagestoolbarnewpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/toolbar/new.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/toolbar/new.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/toolbar/new.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/toolbar/new.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/toolbar/new.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagestoolbarrefreshpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/toolbar/refresh.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/toolbar/refresh.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/toolbar/refresh.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/toolbar/refresh.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/toolbar/refresh.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkimagestoolbarwppng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/images/toolbar/wp.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/images/toolbar/wp.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/images/toolbar/wp.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/images/toolbar/wp.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/images/toolbar/wp.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkindexhtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/index.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/index.html (rev 0)
+++ 2013/sayaksarkar/trunk/index.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>WordPress</title>
+ <link rel="shortcut icon" href="assets/favicon.png"/>
+ <!-- -->
+ <meta http-equiv="Content-Type" content="text/html; charset=utf8"/>
+ <meta name="apple-mobile-web-app-capable" content="yes"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
+ <!-- Less.js (uncomment for client-side rendering of less stylesheets; leave commented to use only CSS) -->
+ <!-- <script src="enyo/tools/minifier/node_modules/less/dist/less-1.3.0e.min.js"></script> -->
+ <!-- enyo (debug) -->
+ <script src="enyo/enyo.js"></script>
+ <!-- application (debug) -->
+ <script src="source/package.js" type="text/javascript"></script>
+ </head>
+ <body class="enyo-unselectable">
+ <script>
+ new wp.Posts().renderInto(document.body);
+ </script>
+ </body>
+</html>
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutCONTRIBUTINGmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/CONTRIBUTING md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/CONTRIBUTING md (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/CONTRIBUTING md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+# Contributions
+
+Contributions are welcome for Enyo and its associated libraries including onyx and layout.
+
+Please see [Contributing to Enyo](http://enyojs.com/community/contribute/) for details
+on our contribution policy and guidelines for use of the Enyo-DCO-1.0-Signed-off-by
+line in your commits and pull requests.
+
+If you're interested in introducing new kinds, you might also consider hosting your own repo
+and contributing to the [Enyo community gallery](http://enyojs.com/gallery).
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutREADMEmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/README.md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/README.md (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/README.md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+### Looking for the issue tracker?
+It's moved to [https://enyojs.atlassian.net](https://enyojs.atlassian.net).
+
+---
+
+This is a layout library for Enyo 2. This library provides a collection of
+layout functionality
+
+## List
+
+The list package provides a `List` control that displays a scrolling list of
+rows. It's suitable for displaying very large lists and is optimized such that
+only a small portion of the list is rendered at a given time.
+
+Check out the List samples in the Layout section of the
+[Enyo Sampler](http://enyojs.com/sampler/) to see the control in action. For
+more information, see the [List documentation](https://github.com/enyojs/enyo/wiki/Lists)
+in the Enyo Developer Guide.
+
+## Fittable
+
+The fittable package helps you create layouts that expand to fit available
+space--a common need for apps, but one that has historically been difficult
+to meet using Web technologies.
+
+The `FittableColumns` and `FittableRows` controls let you define views whose
+children are arranged either horizontally or vertically. Within a given view,
+you can designate one child to expand and contract to fit the available space,
+while its siblings retain their natural or explicitly-specified sizes. Fittable
+views may be nested as needed.
+
+If you're thinking that this sounds a lot like a limited version of the CSS
+Flexible Box Model, you're right. Our main objective was to provide a layout
+model with capabilities similar to Flex Box, but with greater browser
+compatibility. We also wanted to impose as few limitations as possible on the
+CSS styling of child components, and to use JavaScript sparingly (we use it to
+calculate the height of fittable elements, but otherwise leave the layout work
+to the browser).
+
+As much as we like them, we want to emphasize that you should only use
+`FittableColumns` and `FittableRows` when you need views to expand and
+contract to fit available space. If you simply want to arrange elements
+horizontally or vertically, you're better off employing standard Web layout
+techniques.
+
+Check out the
+[Fittable sample](http://enyojs.com/samples/fittable/app-layouts.html) to
+see `FittableColumns` and `FittableRows` in action.
+
+## Panels
+
+The `enyo.Panels` kind is designed to satisfy a variety of common use cases
+for application layout. Using `enyo.Panels`, controls may be arranged as
+(among other things) a carousel, a set of collapsing panels, a card stack
+that fades between panels, or a grid.
+
+For more information, see the [Panels documentation](https://github.com/enyojs/enyo/wiki/Panels)
+on the Enyo wiki.
+
+## Slidable
+
+Slideable is a control that can be dragged either left-to-right or up-and-down
+between a minimum and a maximum value. When released from dragging, a Slideable
+will animate to its minimum or maximum position based on the direction dragged.
+
+## Tree
+
+Tree is a control showing a vertical list of labels with nesting and collapsing
+of hierarchy levels. There's a simple example in the
+[Enyo Sampler](http://enyojs.com/sampler/) showing the control in use as a
+directory and file tree.
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutdeploybat"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/deploy.bat ( => )</h4>
<pre class="diff"><span>
<span class="info">Index: 2013/sayaksarkar/trunk/lib/layout/deploy.sh
===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/deploy.sh 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/deploy.sh 2013-07-23 16:49:28 UTC (rev 2146)
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutdeploysh"></a>
<div class="propset"><h4>Property changes: 2013/sayaksarkar/trunk/lib/layout/deploy.sh</h4>
<pre class="diff"><span>
</span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutdesignjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/design.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/design.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/design.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,155 @@
</span><ins>+/**
+ Descriptions to make layout kinds available in Ares.
+*/
+Palette.model.push(
+ {name: "fittable", items: [
+ {name: "FittableRows", description: "Vertical stacked layout",
+ inline: {kind: "FittableRows", style: "height: 80px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightblue; border: 1px dotted blue; height: 15px;"},
+ {style: "background-color: lightblue; border: 1px dotted blue;", fit: true},
+ {style: "background-color: lightblue; border: 1px dotted blue; height: 15px;"}
+ ]},
+ config: {content: "$name", isContainer: true, kind: "FittableRows"}
+ },
+ {name: "FittableColumns", description: "Horizontal stacked layout",
+ inline: {kind: "FittableColumns", style: "height: 60px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightblue; border: 1px dotted blue; width: 20px;"},
+ {style: "background-color: lightblue; border: 1px dotted blue;", fit: true},
+ {style: "background-color: lightblue; border: 1px dotted blue; width: 20px;"}
+ ]},
+ config: {content: "$name", isContainer: true, kind: "FittableColumns"}
+ }
+ ]},
+ {name: "imageview", items: [
+ {name: "ImageCarousel", description: "A carousel of images",
+ inline: {},
+ config: {content: "$name", isContainer: true, kind: "ImageCarousel"}
+ },
+ {name: "ImageView", description: "A scalable Image View",
+ inline: {},
+ config: {content: "$name", isContainer: true, kind: "ImageView"}
+ },
+ {name: "ImageViewPin", description: "An unscaled item inside an ImageView",
+ inline: {},
+ config: {content: "$name", isContainer: true, kind: "ImageViewPin"}
+ },
+ ]},
+ {name: "List", items: [
+ {name: "AroundList", description: "List with elements above the list",
+ inline: {kind: "FittableRows", style: "height: 80px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; height: 10px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green; height: 10px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green;", fit: true, content: ". . ."},
+ {style: "background-color: lightgreen; border: 1px dotted green; height: 10px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green; height: 10px;"}
+ ]},
+ config: {content: "$name", isContainer: false, kind: "AroundList", onSetupItem: "", count: 0}
+ },
+ {name: "List", description: "Infinite scrolling list",
+ inline: {kind: "FittableRows", style: "height: 80px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; height: 10px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green; height: 10px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green;", fit: true, content: ". . ."},
+ {style: "background-color: lightgreen; border: 1px dotted green; height: 10px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green; height: 10px;"}
+ ]},
+ config: {content: "$name", isContainer: false, kind: "List", onSetupItem: "", count: 0}
+ },
+ {name: "PulldownList", description: "List with pull-to-refresh",
+ inline: {kind: "FittableRows", style: "height: 80px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; height: 10px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green; height: 10px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green;", fit: true, content: ". . ."},
+ {style: "background-color: lightgreen; border: 1px dotted green; height: 10px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green; height: 10px;"}
+ ]},
+ config: {content: "$name", isContainer: false, kind: "PulldownList", onSetupItem: "", count: 0}
+ }
+ ]},
+ {name: "Panels", items: [
+ {name: "CardArranger", description: "Selectable sub-view",
+ inline: {kind: "FittableColumns", style: "height: 60px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green;", fit: true},
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"}
+ ]},
+ config: {content: "$name", isContainer: true, kind: "Panels", arrangerKind: "CardArranger"}
+ },
+ {name: "CardSlideInArranger", description: "Selectable sub-view",
+ inline: {kind: "FittableColumns", style: "height: 60px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green;", fit: true},
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"}
+ ]},
+ config: {content: "$name", isContainer: true, kind: "Panels", arrangerKind: "CardSlideInArranger"}
+ },
+ {name: "CarouselArranger", description: "Selectable sub-view",
+ inline: {kind: "FittableColumns", style: "height: 60px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green;", fit: true},
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"}
+ ]},
+ config: {content: "$name", isContainer: true, kind: "Panels", arrangerKind: "CarouselArranger"}
+ },
+ {name: "CollapsingArranger", description: "Selectable sub-view",
+ inline: {kind: "FittableColumns", style: "height: 60px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green;", fit: true},
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"}
+ ]},
+ config: {content: "$name", isContainer: true, kind: "Panels", arrangerKind: "CollapsingArranger", components: [
+ {content: "Placeholder"}
+ ]}
+ },
+ {name: "DockRightArranger", description: "Selectable sub-view",
+ inline: {kind: "FittableColumns", style: "height: 60px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green;", fit: true},
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"}
+ ]},
+ config: {content: "$name", isContainer: true, kind: "Panels", arrangerKind: "DockRightArranger"}
+ },
+ {name: "GridArranger", description: "Selectable sub-view",
+ inline: {kind: "FittableColumns", style: "height: 60px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green;", fit: true},
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"}
+ ]},
+ config: {content: "$name", isContainer: true, kind: "Panels", arrangerKind: "GridArranger"}
+ },
+ {name: "LeftRightArranger", description: "Selectable sub-view",
+ inline: {kind: "FittableColumns", style: "height: 60px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green;", fit: true},
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"}
+ ]},
+ config: {content: "$name", isContainer: true, kind: "Panels", arrangerKind: "LeftRightArranger"}
+ },
+ {name: "UpDownArranger", description: "Selectable sub-view",
+ inline: {kind: "FittableColumns", style: "height: 60px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"},
+ {style: "background-color: lightgreen; border: 1px dotted green;", fit: true},
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"}
+ ]},
+ config: {content: "$name", isContainer: true, kind: "Panels", arrangerKind: "UpDownArranger"}
+ },
+ ]},
+ {name: "Slideable", items: [
+ {name: "Slideable", description: "Slideable sub-view",
+ inline: {kind: "FittableColumns", style: "height: 40px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"},
+ {style: "background-color: lightblue; border: 1px dotted blue;", fit: true}
+ ]},
+ config: {content: "$name", isContainer: true, kind: "Slideable"}
+ }
+ ]},
+ {name: "Tree", items: [
+ {name: "Node", description: "A tree node",
+ inline: {kind: "FittableColumns", style: "height: 40px; position: relative;", padding: 4, components: [
+ {style: "background-color: lightgreen; border: 1px dotted green; width: 20px;"},
+ {style: "background-color: lightblue; border: 1px dotted blue;", fit: true},
+ ]},
+ config: {content: "$name", isContainer: true, kind: "Node"}
+ }
+ ]}
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablepackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+enyo.depends(
+ "source"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout1html"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout1.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout1.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout1.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Fittable App Layout 1</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="FittableAppLayout1.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.FittableAppLayout1().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout1js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout1.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout1.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout1.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.FittableAppLayout1",
+ kind: "FittableRows",
+ classes: "enyo-fit",
+ components: [
+ {kind: "onyx.Toolbar", components: [
+ {content: "Header"},
+ {kind: "onyx.Button", content: "Button"},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input"}
+ ]}
+ ]},
+ {kind: "FittableColumns", fit: true, components: [
+ {style: "width: 30%;"},
+ {kind: "FittableRows", fit: true, classes: "fittable-sample-shadow", components: [
+ {classes: "fittable-sample-shadow2", style: "height: 30%; position: relative; z-index: 1;"},
+ {fit: true, classes: "fittable-sample-fitting-color"}
+ ]}
+ ]}
+ ]
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout2html"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout2.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout2.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout2.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Fittable App Layout 2</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="FittableAppLayout2.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.FittableAppLayout2().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout2js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout2.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout2.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout2.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.FittableAppLayout2",
+ kind: "FittableColumns",
+ classes: "enyo-fit",
+ components: [
+ {kind: "FittableRows", style: "width: 20%;", components: [
+ {fit: true},
+ {kind: "onyx.Toolbar", components: [
+ {kind: "onyx.Button", content: "1"}
+ ]}
+ ]},
+ {kind: "FittableRows", style: "width: 20%;", classes: "fittable-sample-shadow", components: [
+ {fit: true, style: ""},
+ {kind: "onyx.Toolbar", components: [
+ {kind: "onyx.Button", content: "2"}
+ ]}
+ ]},
+ {kind: "FittableRows", fit: true, classes: "fittable-sample-shadow", components: [
+ {fit: true, classes: "fittable-sample-fitting-color"},
+ {kind: "onyx.Toolbar", components: [
+ {kind: "onyx.Button", content: "3"}
+ ]}
+ ]}
+ ]
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout3html"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout3.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout3.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout3.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Fittable App Layout 3</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="FittableAppLayout3.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.FittableAppLayout3().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout3js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout3.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout3.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout3.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.FittableAppLayout3",
+ kind: "FittableColumns",
+ classes: "enyo-fit",
+ components: [
+ {kind: "FittableRows", fit: true, components: [
+ {fit: true, classes: "fittable-sample-fitting-color"},
+ {classes: "fittable-sample-shadow3", style: "height: 30%; position: relative;"},
+ {kind: "onyx.Toolbar", components: [
+ {kind: "onyx.Button", content: "1"}
+ ]}
+ ]},
+ {kind: "FittableRows", classes: "fittable-sample-shadow", style: "width: 30%; position: relative;", components: [
+ {fit: true},
+ {kind: "onyx.Toolbar", components: [
+ {kind: "onyx.Button", content: "2"}
+ ]}
+ ]}
+ ]
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout4html"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout4.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout4.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout4.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Fittable App Layout 4</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="FittableAppLayout4.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.FittableAppLayout4().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableAppLayout4js"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout4.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout4.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableAppLayout4.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.FittableAppLayout4",
+ kind: "FittableColumns",
+ classes: "enyo-fit",
+ components: [
+ {kind: "FittableRows", classes: "fittable-sample-shadow4", style: "width: 30%; position: relative; z-index: 1;", components: [
+ {style: "height: 20%;"},
+ {style: "height: 20%;"},
+ {fit: true},
+ {kind: "onyx.Toolbar", style: "height: 57px;", components: [
+ {content: "Toolbar"}
+ ]}
+ ]},
+ {kind: "FittableRows", fit: true, components: [
+ {fit: true, classes: "fittable-sample-fitting-color"},
+ {kind: "onyx.Toolbar", style: "height: 57px;",components: [
+ {kind: "onyx.Button", content: "2"}
+ ]}
+ ]}
+ ]
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableDescriptionhtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableDescription.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableDescription.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableDescription.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Fittables Description</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="FittableDescription.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.FittableDescription().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableDescriptionjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableDescription.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableDescription.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableDescription.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.FittableDescription",
+ classes: "fittable-sample-box enyo-fit",
+ style: "padding:10px;",
+ kind: "Scroller",
+ components: [
+ {tag: "p", allowHtml: true, content: "FittableColumns, no margin on boxes (all divs have some padding). By default, boxes 'stretch' to fit the container (which must have a height)."},
+ {kind: "FittableColumns", classes: "fittable-sample-height fittable-sample-box fittable-sample-o fittable-sample-mlr fittable-sample-mtb", components: [
+ {content: "BoxA", classes: "fittable-sample-box"},
+ {content: "Fitting BoxB", fit: true, classes: "fittable-sample-box"},
+ {content: "BoxC", classes: "fittable-sample-box"}
+ ]},
+ {tag: "p", allowHtml: true, content: "Boxes with left/right margins. Note: top/bottom margin on column boxes is NOT supported."},
+ {kind: "FittableColumns", classes: "fittable-sample-height fittable-sample-box fittable-sample-o fittable-sample-mlr fittable-sample-mtb", components: [
+ {content: "BoxA", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "Fitting BoxB", fit: true, classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "BoxC", classes: "fittable-sample-box fittable-sample-mlr"}
+ ]},
+ {tag: "p", allowHtml: true, content: "With <code>noStretch: true</code>, boxes have natural height."},
+ {kind: "FittableColumns", noStretch: true, classes: "fittable-sample-height fittable-sample-box fittable-sample-o fittable-sample-mlr fittable-sample-mtb", components: [
+ {content: "BoxA", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "Fitting BoxB<br><br>with natural height", fit: true, allowHtml: true, classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "BoxC", classes: "fittable-sample-box fittable-sample-mlr"}
+ ]},
+ {tag: "p", allowHtml: true, content: "FittableRows, no margin on boxes (all divs have some padding)."},
+ {kind: "FittableRows", classes: "fittable-sample-height fittable-sample-box fittable-sample-o fittable-sample-mlr fittable-sample-mtb", components: [
+ {content: "BoxA", classes: "fittable-sample-box"},
+ {content: "Fitting BoxB", fit: true, classes: "fittable-sample-box"},
+ {content: "BoxC", classes: "fittable-sample-box"}
+ ]},
+ {tag: "p", allowHtml: true, content: "Row boxes may have margin in any dimension.<br><br> NOTE: Row boxes will collapse vertical margins according to css rules. If margin collapse is not desired, then \"enyo-margin-expand\" may be applied. Only in this case, left/right margin on row boxes is NOT supported."},
+ {kind: "FittableRows", classes: "fittable-sample-height fittable-sample-box fittable-sample-o fittable-sample-mlr fittable-sample-mtb", components: [
+ {content: "BoxA", classes: "fittable-sample-box fittable-sample-mlr fittable-sample-mtb"},
+ {content: "Fitting BoxB", fit: true, classes: "fittable-sample-box fittable-sample-mlr fittable-sample-mtb"},
+ {content: "BoxC", classes: "fittable-sample-box fittable-sample-mlr fittable-sample-mtb"}
+ ]},
+ {tag: "p", allowHtml: true, content: "With <code>noStretch: true</code>, boxes have natural width.<br><br> NOTE: margins will not collapse in this case."},
+ {kind: "FittableRows", noStretch: true, classes: "fittable-sample-height fittable-sample-box fittable-sample-o fittable-sample-mtb", components: [
+ {content: "BoxA", classes: "fittable-sample-box fittable-sample-mlr fittable-sample-mtb"},
+ {content: "Fitting BoxB", fit: true, classes: "fittable-sample-box fittable-sample-mlr fittable-sample-mtb"},
+ {content: "BoxC", classes: "fittable-sample-box fittable-sample-mlr fittable-sample-mtb"}
+ ]}
+ ]
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Fittables Basic Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="FittableSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.FittableSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.FittableSample",
+ kind: "FittableRows",
+ classes: "fittable-sample-box enyo-fit",
+ components: [
+ {content: "Foo<br>Foo", allowHtml: true, classes: "fittable-sample-box fittable-sample-mtb"},
+ {content: "Foo<br>Foo", allowHtml: true, classes: "fittable-sample-box fittable-sample-mtb"},
+ {kind: "FittableColumns", fit: true, classes: "fittable-sample-box fittable-sample-mtb fittable-sample-o", components: [
+ {content: "Foo", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "Foo", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "Fits!", fit: true, classes: "fittable-sample-box fittable-sample-mlr fittable-sample-o"},
+ {content: "Foo", classes: "fittable-sample-box fittable-sample-mlr"}
+ ]},
+ {kind: "FittableColumns", content: "Bat", classes: "fittable-sample-box fittable-sample-mtb enyo-center", components: [
+ {content: "Centered", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "1", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "2", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "3", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "4", classes: "fittable-sample-box fittable-sample-mlr"}
+ ]}
+ ]
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableTestshtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableTests.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableTests.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableTests.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Fittable Tests</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="FittableTests.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.FittableTests().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplesFittableTestsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableTests.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableTests.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/FittableTests.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,84 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.FittableTests",
+ classes: "fittable-sample-box enyo-fit",
+ kind: "Scroller",
+ components: [
+ {classes: "fittable-sample-section", content: "Rows/Columns using a combination of css units and highlighting margin collapse"},
+ {kind: "FittableRows", classes: "fittable-sample-box fittable-sample-test", style: "height: 400px;", components: [
+ {content: "FOO<br>margin-bottom: 1em", allowHtml: true, classes: "fittable-sample-box fittable-sample-mlr fittable-sample-mtb", style: "margin-bottom: 1em;"},
+ {content: "margin-top: 1em (collapsed since sibling shows greater of previous bottom and this top)<br>FOO", allowHtml: true, classes: "fittable-sample-box fittable-sample-mlr fittable-sample-mtb", style: "margin-top: 1em;"},
+ {content: "FOO<br>FOO", allowHtml: true, classes: "fittable-sample-box fittable-sample-mlr fittable-sample-mtb"},
+ {kind: "FittableColumns", fit: true, classes: "fittable-sample-box fittable-sample-mtb fittable-sample-mlr fittable-sample-o", components: [
+ {content: "111111111111111", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "111111111111111", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "2", fit: true, classes: "fittable-sample-box fittable-sample-mlr fittable-sample-o"},
+ {content: "3333333", classes: "fittable-sample-box fittable-sample-mlr"}
+ ]},
+ {kind: "FittableColumns", content: "Bat", classes: "fittable-sample-box fittable-sample-mtb enyo-center", components: [
+ {content: "add enyo-center to FittableColumns", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "1", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "2", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "3", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "4", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "5", classes: "fittable-sample-box fittable-sample-mlr"}
+ ]}
+ ]},
+ {classes: "fittable-sample-section", content: "Rows with enyo-margin-expand to avoid margin-collapse"},
+ {kind: "FittableRows", classes: "fittable-sample-box fittable-sample-test enyo-margin-expand", style: "height: 250px;", components: [
+ {content: "FOO<br>margin-bottom: 1em", allowHtml: true, classes: "fittable-sample-box fittable-sample-mtb", style: "margin-bottom: 1em;"},
+ {content: "margin-top: 3em (not collapsed due to enyo-margin-expand on box)<br>FOO", allowHtml: true, classes: "fittable-sample-box fittable-sample-mtb", style: "margin-top: 3em;"},
+ {content: "FOO<br>FOO", allowHtml: true, fit: true, classes: "fittable-sample-box fittable-sample-mtb"}
+ ]},
+ {classes: "fittable-sample-section", content: "Tests to ensure fit region can be first, middle, or last"},
+ {kind: "FittableRows", classes: "fittable-sample-boxable fittable-sample-small-test", components: [
+ {content: "A", fit: true},
+ {content: "B"},
+ {content: "C"}
+ ]},
+ {kind: "FittableRows", classes: "fittable-sample-boxable fittable-sample-small-test", components: [
+ {content: "A"},
+ {content: "B", fit: true},
+ {content: "C"}
+ ]},
+ {kind: "FittableRows", classes: "fittable-sample-boxable fittable-sample-small-test", components: [
+ {content: "A"},
+ {content: "B"},
+ {content: "C", fit: true}
+ ]},
+ {kind: "FittableColumns", classes: "fittable-sample-boxable fittable-sample-small-test", components: [
+ {content: "A", fit: true},
+ {content: "B"},
+ {content: "C"}
+ ]},
+ {kind: "FittableColumns", classes: "fittable-sample-boxable fittable-sample-small-test", components: [
+ {content: "A"},
+ {content: "B", fit: true},
+ {content: "C"}
+ ]},
+ {style: "height: 200px;", kind: "FittableColumns", classes: "fittable-sample-boxable fittable-sample-small-test", components: [
+ {content: "A"},
+ {content: "B"},
+ {content: "C", fit: true}
+ ]},
+ {classes: "fittable-sample-section", content: "Tests for noStretch: true"},
+ {kind: "FittableRows", classes: "fittable-sample-box fittable-sample-test", style: "height: 400px;", noStretch: true, components: [
+ {content: "FOO<br>margin-bottom: 1em", allowHtml: true, classes: "fittable-sample-box fittable-sample-mlr fittable-sample-mtb", style: "margin-bottom: 1em;"},
+ {content: "margin-top: 2em (not collapsed; stretch false does not collapse due to use of float)<br>FOO", allowHtml: true, classes: "fittable-sample-box fittable-sample-mlr fittable-sample-mtb", style: "margin-top: 1em;"},
+ {content: "FOO<br>FOO", allowHtml: true, classes: "fittable-sample-box fittable-sample-mlr fittable-sample-mtb"},
+ {kind: "FittableColumns", fit: true, noStretch: true, classes: "fittable-sample-box fittable-sample-mtb fittable-sample-mlr fittable-sample-o", components: [
+ {content: "111111111111111", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "111111111111111", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "2<br>2", allowHtml: true, fit: true, classes: "fittable-sample-box fittable-sample-mlr fittable-sample-o"},
+ {content: "3333333", classes: "fittable-sample-box fittable-sample-mlr"}
+ ]},
+ {kind: "FittableColumns", content: "Bat", noStretch: true, classes: "fittable-sample-box fittable-sample-mtb enyo-center", components: [
+ {content: "add enyo-center to FittableColumns", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "1", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "2", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "3", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "4", classes: "fittable-sample-box fittable-sample-mlr"},
+ {content: "5", classes: "fittable-sample-box fittable-sample-mlr"}
+ ]}
+ ]}
+ ]
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplespackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+enyo.depends(
+ "sample.css",
+ "FittableSample.js",
+ "FittableAppLayout1.js",
+ "FittableAppLayout2.js",
+ "FittableAppLayout3.js",
+ "FittableAppLayout4.js",
+ "FittableDescription.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesamplessamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/samples/sample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/samples/sample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/samples/sample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,76 @@
</span><ins>+.fittable-sample-box {
+ border: 2px solid lightblue;
+ padding: 4px;
+}
+.fittable-sample-b {
+ background-color: #F1FFF1;
+}
+.fittable-sample-mtb {
+ margin-top: 3px;
+ margin-bottom: 3px;
+}
+.fittable-sample-mlr {
+ margin-left: 6px;
+ margin-right: 6px;
+}
+.fittable-sample-o {
+ border-color: orange;
+}
+.fittable-sample-height {
+ height: 140px;
+}
+
+.fittable-sample-fitting-color {
+ background: #B7BFC4;
+}
+
+.fittable-sample-shadow {
+ box-shadow: -6px 0px 6px rgba(0,0,0,0.3);
+ -moz-box-shadow: -6px 0px 6px rgba(0,0,0,0.3);
+ -webkit-box-shadow: -6px 0px 6px rgba(0,0,0,0.3);
+}
+
+.fittable-sample-shadow2 {
+ box-shadow: 6px 6px 6px rgba(0,0,0,0.3);
+ -moz-box-shadow: 6px 6px 6px rgba(0,0,0,0.3);
+ -webkit-box-shadow: 6px 6px 6px rgba(0,0,0,0.3);
+}
+
+.fittable-sample-shadow3 {
+ box-shadow: 0 -6px 6px rgba(0,0,0,0.3);
+ -moz-box-shadow: 0 -6px 6px rgba(0,0,0,0.3);
+ -webkit-box-shadow: 0 -6px 6px rgba(0,0,0,0.3);
+}
+
+.fittable-sample-shadow4 {
+ box-shadow: 6px 0px 6px rgba(0,0,0,0.3);
+ -moz-box-shadow: 6px 0px 6px rgba(0,0,0,0.3);
+ -webkit-box-shadow: 6px 0px 6px rgba(0,0,0,0.3);
+}
+
+.fittable-sample-boxable {
+ margin: 0.5em;
+ padding: 1em;
+ border: 0.2em solid beige;
+}
+
+.fittable-sample-boxable > * {
+ border: 0.1em dotted orange;
+ padding: 0.5em;
+}
+
+.fittable-sample-test {
+ border-width: 0.2em;
+ border-color: red;
+}
+
+.fittable-sample-small-test {
+ border-width: 0.2em;
+ border-color: red;
+ height: 150px;
+}
+
+.fittable-sample-section {
+ padding: 30px 10px 10px;
+ font-weight: bold;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesourceFittableColumnsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableColumns.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableColumns.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableColumns.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+/**
+ _enyo.FittableColumns_ provides a container in which items are laid out in a
+ set of vertical columns, with most items having natural size, but one
+ expanding to fill the remaining space. The one that expands is labeled with
+ the attribute _fit: true_.
+
+ For more information, see the documentation on
+ [Fittables](https://github.com/enyojs/enyo/wiki/Fittables) in the Enyo
+ Developer Guide.
+
+*/
+
+enyo.kind({
+ name: "enyo.FittableColumns",
+ layoutKind: "FittableColumnsLayout",
+ /** By default, items in columns stretch to fit vertically; set to true to
+ avoid this behavior */
+ noStretch: false
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesourceFittableLayoutcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableLayout.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableLayout.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableLayout.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+.enyo-fittable-rows-layout {
+ position: relative;
+}
+
+.enyo-fittable-rows-layout > * {
+ box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ /* float when not stretched */
+ float: left;
+ clear: both;
+}
+
+/* non-floating when stretched */
+.enyo-fittable-rows-layout.enyo-stretch > * {
+ float: none;
+ clear: none;
+}
+
+/* setting to enforce margin collapsing */
+/* NOTE: rows cannot have margin left/right */
+.enyo-fittable-rows-layout.enyo-stretch.enyo-margin-expand > * {
+ float: left;
+ clear: both;
+ width: 100%;
+ /* note: harsh resets */
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+}
+
+.enyo-fittable-columns-layout {
+ position: relative;
+ text-align: left;
+ white-space: nowrap;
+}
+
+.enyo-fittable-columns-layout.enyo-center {
+ text-align: center;
+}
+
+.enyo-fittable-columns-layout > * {
+ box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ vertical-align: top;
+ display: inline-block;
+ white-space: normal;
+}
+
+.enyo-fittable-columns-layout.enyo-tool-decorator > * {
+ vertical-align: middle;
+}
+
+/* repair clobbered white-space setting for pre, code */
+.enyo-fittable-columns-layout > pre, .enyo-fittable-columns-layout > code {
+ white-space: pre;
+}
+
+.enyo-fittable-columns-layout > .enyo-fittable-columns-layout, .enyo-fittable-columns-layout > .onyx-toolbar-inline {
+ white-space: nowrap;
+}
+
+/* NOTE: columns cannot have margin top/bottom */
+.enyo-fittable-columns-layout.enyo-stretch > * {
+ height: 100%;
+ /* note: harsh resets */
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesourceFittableLayoutjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableLayout.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableLayout.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableLayout.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,156 @@
</span><ins>+/**
+ _enyo.FittableLayout_ provides the base positioning and boundary logic for
+ the fittable layout strategy. The fittable layout strategy is based on
+ laying out items in either a set of rows or a set of columns, with most of
+ the items having natural size, but one item expanding to fill the remaining
+ space. The item that expands is labeled with the attribute _fit: true_.
+
+ The subkinds <a href="#enyo.FittableColumnsLayout">enyo.FittableColumnsLayout</a>
+ and <a href="#enyo.FittableRowsLayout">enyo.FittableRowsLayout</a> (or
+ <i>their</i> subkinds) are used for layout rather than _enyo.FittableLayout_
+ because they specify properties that the framework expects to be available
+ when laying items out.
+
+ For more information,see the documentation on
+ [Fittables](https://github.com/enyojs/enyo/wiki/Fittables) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.FittableLayout",
+ kind: "Layout",
+ //* @protected
+ calcFitIndex: function() {
+ for (var i=0, c$=this.container.children, c; (c=c$[i]); i++) {
+ if (c.fit && c.showing) {
+ return i;
+ }
+ }
+ },
+ getFitControl: function() {
+ var c$=this.container.children;
+ var f = c$[this.fitIndex];
+ if (!(f && f.fit && f.showing)) {
+ this.fitIndex = this.calcFitIndex();
+ f = c$[this.fitIndex];
+ }
+ return f;
+ },
+ getLastControl: function() {
+ var c$=this.container.children;
+ var i = c$.length-1;
+ var c = c$[i];
+ while ((c=c$[i]) && !c.showing) {
+ i--;
+ }
+ return c;
+ },
+ _reflow: function(measure, cMeasure, mAttr, nAttr) {
+ this.container.addRemoveClass("enyo-stretch", !this.container.noStretch);
+ var f = this.getFitControl();
+ // no sizing if nothing is fit.
+ if (!f) {
+ return;
+ }
+ //
+ // determine container size, available space
+ var s=0, a=0, b=0, p;
+ var n = this.container.hasNode();
+ // calculate available space
+ if (n) {
+ // measure 1
+ p = enyo.dom.calcPaddingExtents(n);
+ // measure 2
+ s = n[cMeasure] - (p[mAttr] + p[nAttr]);
+ //enyo.log("overall size", s);
+ }
+ //
+ // calculate space above fitting control
+ // measure 3
+ var fb = f.getBounds();
+ // offset - container padding.
+ a = fb[mAttr] - ((p && p[mAttr]) || 0);
+ //enyo.log("above", a);
+ //
+ // calculate space below fitting control
+ var l = this.getLastControl();
+ if (l) {
+ // measure 4
+ var mb = enyo.dom.getComputedBoxValue(l.hasNode(), "margin", nAttr) || 0;
+ if (l != f) {
+ // measure 5
+ var lb = l.getBounds();
+ // fit offset + size
+ var bf = fb[mAttr] + fb[measure];
+ // last offset + size + ending margin
+ var bl = lb[mAttr] + lb[measure] + mb;
+ // space below is bottom of last item - bottom of fit item.
+ b = bl - bf;
+ } else {
+ b = mb;
+ }
+ }
+
+ // calculate appropriate size for fit control
+ var fs = s - (a + b);
+ //enyo.log(f.id, fs);
+ // note: must be border-box;
+ f.applyStyle(measure, fs + "px");
+ },
+ //* @public
+ /**
+ Updates the layout to reflect any changes to contained components or the
+ layout container.
+ */
+ reflow: function() {
+ if (this.orient == "h") {
+ this._reflow("width", "clientWidth", "left", "right");
+ } else {
+ this._reflow("height", "clientHeight", "top", "bottom");
+ }
+ }
+});
+
+/**
+ _enyo.FittableColumnsLayout_ provides a container in which items are laid
+ out in a set of vertical columns, with most of the items having natural
+ size, but one expanding to fill the remaining space. The one that expands is
+ labeled with the attribute _fit: true_.
+
+ _enyo.FittableColumnsLayout_ is meant to be used as a value for the
+ _layoutKind_ property of other kinds. _layoutKind_ provides a way to add
+ layout behavior in a pluggable fashion while retaining the ability to use a
+ specific base kind.
+
+ For more information, see the documentation on
+ [Fittables](https://github.com/enyojs/enyo/wiki/Fittables) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.FittableColumnsLayout",
+ kind: "FittableLayout",
+ orient: "h",
+ layoutClass: "enyo-fittable-columns-layout"
+});
+
+
+/**
+ _enyo.FittableRowsLayout_ provides a container in which items are laid out
+ in a set of horizontal rows, with most of the items having natural size, but
+ one expanding to fill the remaining space. The one that expands is labeled
+ with the attribute _fit: true_.
+
+ _enyo.FittableRowsLayout_ is meant to be used as a value for the
+ _layoutKind_ property of other kinds. _layoutKind_ provides a way to add
+ layout behavior in a pluggable fashion while retaining the ability to use a
+ specific base kind.
+
+ For more information, see the documentation on
+ [Fittables](https://github.com/enyojs/enyo/wiki/Fittables) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.FittableRowsLayout",
+ kind: "FittableLayout",
+ layoutClass: "enyo-fittable-rows-layout",
+ orient: "v"
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesourceFittableRowsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableRows.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableRows.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/source/FittableRows.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+/**
+ _enyo.FittableRows_ provides a container in which items are laid out in a
+ set of horizontal rows, with most of the items having natural size, but one
+ expanding to fill the remaining space. The one that expands is labeled with
+ the attribute _fit: true_.
+
+ For more information, see the documentation on
+ [Fittables](https://github.com/enyojs/enyo/wiki/Fittables) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.FittableRows",
+ layoutKind: "FittableRowsLayout",
+ /** By default, items in rows stretch to fit horizontally; set to true to
+ avoid this behavior */
+ noStretch: false
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutfittablesourcepackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/fittable/source/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/fittable/source/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/fittable/source/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+enyo.depends(
+ "FittableLayout.css",
+ "FittableLayout.js",
+ "FittableRows.js",
+ "FittableColumns.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutimageviewpackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/imageview/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/imageview/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+enyo.depends(
+ "source/"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutimageviewsamplesImageCarouselSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageCarouselSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageCarouselSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageCarouselSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+.imagecarousel-sample-input {
+ margin:0px 6px;
+}
+
+.imagecarousel-sample-input input {
+ text-align:center;
+ width:30px;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutimageviewsamplesImageCarouselSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageCarouselSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageCarouselSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageCarouselSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Image Carousel Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="ImageCarouselSample.css" rel="stylesheet">
+ <script src="ImageCarouselSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.ImageCarouselSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutimageviewsamplesImageCarouselSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageCarouselSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageCarouselSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageCarouselSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.ImageCarouselSample",
+ kind: "FittableRows",
+ classes: "enyo-fit",
+ components: [
+ {kind: "onyx.Toolbar", style:"text-align:center;", components: [
+ {kind: "onyx.Button", content:"←", allowHtml: true, ontap:"previous"},
+ {kind: "onyx.Button", content:"→", allowHtml: true, ontap:"next"},
+ {kind: "onyx.InputDecorator", classes: "imagecarousel-sample-input", components: [
+ {name: "carouselIndexInput", kind: "onyx.Input", value: "0", onchange: "updateIndex"}
+ ]}
+ ]},
+ {name:"carousel", kind:"ImageCarousel", fit:true, onload:"load", onZoom:"zoom", onerror:"error", onTransitionStart: "transitionStart", onTransitionFinish: "transitionFinish"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.urls = [
+ "assets/mercury.jpg",
+ "assets/venus.jpg",
+ "assets/earth.jpg",
+ "assets/mars.jpg",
+ "assets/jupiter.jpg",
+ "assets/saturn.jpg",
+ "assets/uranus.jpg",
+ "assets/neptune.jpg"
+ ];
+ // although we're specifying all the image urls now, the images themselves
+ // only get created/loaded as needed
+ this.$.carousel.setImages(this.urls);
+ },
+ load: function(inSender, inEvent) {
+ //enyo.log("image loaded: " + inEvent.originator.src);
+ },
+ zoom: function(inSender, inEvent) {
+ //enyo.log("image zoomed: " + inEvent.scale + " scale on " + inEvent.originator.src);
+ },
+ error: function(inSender, inEvent) {
+ //enyo.log("image error: " + inEvent.originator.src);
+ },
+ transitionStart: function(inSender, inEvent) {
+ //enyo.log("image now transitioning from: " + this.$.carousel.getImageByIndex(inEvent.fromIndex).src
+ // + " to " + this.$.carousel.getImageByIndex(inEvent.toIndex).src);
+ },
+ transitionFinish: function(inSender, inEvent) {
+ //enyo.log("image transitioned to: " + this.$.carousel.getActiveImage().src);
+ if (this.$.carouselIndexInput) {
+ this.$.carouselIndexInput.setValue(inEvent.toIndex);
+ }
+ },
+ previous: function(inSender, inEvent) {
+ this.$.carousel.previous();
+ },
+ next: function(inSender, inEvent) {
+ this.$.carousel.next();
+ },
+ getRandomIndex: function() {
+ var i = Math.floor(Math.random()*this.$.carousel.images.length);
+ while(i==this.$.carousel.index) { //make sure it isn't the active index
+ i = Math.floor(Math.random()*this.$.carousel.images.length);
+ }
+ return i;
+ },
+ updateIndex: function(inSender, inEvent) {
+ var index = this.trimWhitespace(this.$.carouselIndexInput.getValue());
+ if(index === "" || isNaN(index)) {
+ //enyo.log("Numbers only please.")
+ return;
+ }
+ this.$.carousel.setIndex(parseInt(index, 10));
+ },
+ trimWhitespace: function(inString) {
+ return inString.replace(/^\s+|\s+$/g,"");
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutimageviewsamplesImageViewSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageViewSample.css ( => )</h4>
<pre class="diff"><span>
<span class="info">Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageViewSample.html
===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageViewSample.html (rev 0)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageViewSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Image View Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="ImageViewSample.css" rel="stylesheet">
+ <script src="ImageViewSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.ImageViewSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutimageviewsamplesImageViewSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageViewSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageViewSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/ImageViewSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+/**
+ Our map pin icon is based in whole or in part on the OpenStructs open source information and documentation,
+ largely developed by Structured Dynamics LLC. You are free to use this content and system as you wish, so long
+ as any derivative works acknowledge these contributions. TechWiki is provided under the Creative Commons
+ Attribution License, version 3.0. - http://techwiki.openstructs.org/index.php/Open_Source_Icons
+*/
+enyo.kind({
+ name: "enyo.sample.ImageViewSample",
+ components: [
+ {name:"sampleImageView", kind:"ImageView", src:"assets/globe.jpg", scale:"auto", classes:"enyo-fit", components: [
+ {kind: "enyo.ImageViewPin", highlightAnchorPoint:true, anchor: {top:79, right:224}, position: {bottom:0, left:-16}, components: [
+ {kind:"Image", src:"assets/pin.png"}
+ ]},
+ {kind: "enyo.ImageViewPin", anchor: {top:280, left:415}, position: {bottom:0, right:-16}, components: [
+ {kind:"Image", src:"assets/pin.png"}
+ ]},
+ {kind: "enyo.ImageViewPin", highlightAnchorPoint:true, anchor: {bottom:"20%", left:"400px"}, position: {bottom:0, left:0}, components: [
+ {style:"background:rgba(255,255,255,0.8);border:1px solid #888;margin:0px;padding:0px;width:300px", components: [
+ {tag:"h3", content:"This is a text box"}
+ ]}
+ ]},
+ {name:"testPin", kind: "enyo.ImageViewPin", anchor: {top:"10%", right:"10%"}, position: {top:0, left:0}, components: [
+ {style:"border:1px solid yellow;width:10px;background:red;height:10px;"}
+ ]}
+ ]}
+ ]
+});
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutimageviewsamplesassetsearthjpg"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/earth.jpg</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/earth.jpg
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/earth.jpg 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/earth.jpg 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/earth.jpg
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/jpeg
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutimageviewsamplesassetsfaviconico"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/favicon.ico</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/favicon.ico
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/favicon.ico 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/favicon.ico 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/favicon.ico
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/x-icon
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutimageviewsamplesassetsglobejpg"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/globe.jpg</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/globe.jpg
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/globe.jpg 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/globe.jpg 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/globe.jpg
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/jpeg
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutimageviewsamplesassetsjupiterjpg"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/jupiter.jpg</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/jupiter.jpg
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/jupiter.jpg 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/jupiter.jpg 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/jupiter.jpg
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/jpeg
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutimageviewsamplesassetsmarsjpg"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/mars.jpg</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/mars.jpg
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/mars.jpg 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/mars.jpg 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/mars.jpg
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/jpeg
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutimageviewsamplesassetsmercuryjpg"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/mercury.jpg</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/mercury.jpg
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/mercury.jpg 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/mercury.jpg 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/mercury.jpg
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/jpeg
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutimageviewsamplesassetsneptunejpg"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/neptune.jpg</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/neptune.jpg
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/neptune.jpg 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/neptune.jpg 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/neptune.jpg
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/jpeg
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutimageviewsamplesassetspinpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/pin.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/pin.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/pin.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/pin.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/pin.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutimageviewsamplesassetssaturnjpg"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/saturn.jpg</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/saturn.jpg
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/saturn.jpg 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/saturn.jpg 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/saturn.jpg
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/jpeg
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutimageviewsamplesassetsuranusjpg"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/uranus.jpg</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/uranus.jpg
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/uranus.jpg 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/uranus.jpg 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/uranus.jpg
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/jpeg
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutimageviewsamplesassetsvenusjpg"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/venus.jpg</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/venus.jpg
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/venus.jpg 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/venus.jpg 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/assets/venus.jpg
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/jpeg
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutimageviewsamplespackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/samples/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/imageview/samples/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/imageview/samples/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+enyo.depends(
+ "ImageViewSample.js",
+ "ImageViewSample.css",
+ "ImageCarouselSample.js",
+ "ImageCarouselSample.css"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutimageviewsourceImageCarouseljs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageCarousel.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageCarousel.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageCarousel.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,208 @@
</span><ins>+/**
+ _enyo.ImageCarousel_ is an <a href="#enyo.Panels">enyo.Panels</a> that
+ uses <a href="#enyo.CarouselArranger">enyo.CarouselArranger</a> as its
+ arrangerKind. An ImageCarousel dynamically creates and loads instances of
+ <a href="#enyo.ImageView">enyo.ImageView</a> as needed, creating a gallery
+ of images.
+
+ {kind:"ImageCarousel", images:[
+ "assets/mercury.jpg",
+ "assets/venus.jpg",
+ "assets/earth.jpg",
+ "assets/mars.jpg",
+ "assets/jupiter.jpg",
+ "assets/saturn.jpg",
+ "assets/uranus.jpg",
+ "assets/neptune.jpg"
+ ], defaultScale:"auto"},
+
+ All of the events (_onload_, _onerror_, and _onZoom_) from the contained
+ ImageView objects are bubbled up to the ImageCarousel, which also inherits
+ the _onTransitionStart_ and _onTransitionFinish_ events from _enyo.Panels_.
+
+ The _images_ property is an array containing the file paths of the images in
+ the gallery. The _images_ array may be altered and updated at any time, and
+ the current index may be manipulated at runtime via the inherited
+ _getIndex()_ and _setIndex()_ functions.
+
+ Note that it's best to specify a size for the ImageCarousel in order to
+ avoid complications.
+*/
+
+enyo.kind({
+ name: "enyo.ImageCarousel",
+ kind: enyo.Panels,
+ arrangerKind: "enyo.CarouselArranger",
+ /**
+ The default scale value to be applied to each ImageView. Can be "auto",
+ "width", "height", or any positive numeric value.
+ */
+ defaultScale: "auto",
+ //* If true, ImageView instances are created with zooming disabled.
+ disableZoom: false,
+ /**
+ If true, any ImageViews that are not in the immediate viewing area
+ (i.e., the currently active image and the first image on either
+ side of it) will be destroyed to free up memory. This has the benefit of
+ using minimal memory (which is good for mobile devices), but has the
+ downside that, if you want to view the images again, the ImageViews will
+ have to be re-created and the images re-fetched (thus increasing the
+ number of image-related GET calls). Defaults to false.
+ */
+ lowMemory: false,
+ published: {
+ //* Array of image source file paths
+ images:[]
+ },
+ //* @protected
+ handlers: {
+ onTransitionStart: "transitionStart",
+ onTransitionFinish: "transitionFinish"
+ },
+ create: function() {
+ this.inherited(arguments);
+ this.imageCount = this.images.length;
+ if(this.images.length>0) {
+ this.initContainers();
+ this.loadNearby();
+ }
+ },
+ initContainers: function() {
+ for(var i=0; i<this.images.length; i++) {
+ if(!this.$["container" + i]) {
+ this.createComponent({
+ name: "container" + i,
+ style: "height:100%; width:100%;"
+ });
+ this.$["container" + i].render();
+ }
+ }
+ for(i=this.images.length; i<this.imageCount; i++) {
+ if(this.$["image" + i]) {
+ this.$["image" + i].destroy();
+ }
+ this.$["container" + i].destroy();
+ }
+ this.imageCount = this.images.length;
+ },
+ loadNearby: function() {
+ var range = this.getBufferRange();
+ for (var i in range) {
+ this.loadImageView(range[i]);
+ }
+ },
+ getBufferRange: function() {
+ var range = [];
+ if (this.layout.containerBounds) {
+ var prefetchRange = 1;
+ var bounds = this.layout.containerBounds;
+ var m, img, c, i, x, xEnd;
+ // get the lower range
+ i=this.index-1;
+ x=0;
+ xEnd = bounds.width * prefetchRange;
+ while (i>=0 && x<=xEnd) {
+ c = this.$["container" + i];
+ x+= c.width + c.marginWidth;
+ range.unshift(i);
+ i--;
+ }
+ // get the upper range
+ i=this.index;
+ x=0;
+ xEnd = bounds.width * (prefetchRange + 1);
+ while (i<this.images.length && x<=xEnd) {
+ c = this.$["container" + i];
+ x+= c.width + c.marginWidth;
+ range.push(i);
+ i++;
+ }
+ }
+ return range;
+ },
+ reflow: function() {
+ this.inherited(arguments);
+ this.loadNearby();
+ },
+ loadImageView: function(index) {
+ // NOTE: wrap bugged in enyo.CarouselArranger, but once fixed, wrap should work in this
+ if(this.wrap) {
+ // Used this modulo technique to get around javascript issue with negative values
+ // ref: http://javascript.about.com/od/problemsolving/a/modulobug.htm
+ index = ((index % this.images.length)+this.images.length)%this.images.length;
+ }
+ if(index>=0 && index<=this.images.length-1) {
+ if(!this.$["image" + index]) {
+ this.$["container" + index].createComponent({
+ name: "image" + index,
+ kind: "ImageView",
+ scale: this.defaultScale,
+ disableZoom: this.disableZoom,
+ src: this.images[index],
+ verticalDragPropagation: false,
+ style: "height:100%; width:100%;"
+ }, {owner: this});
+ this.$["image" + index].render();
+ } else {
+ if(this.$["image" + index].src != this.images[index]) {
+ this.$["image" + index].setSrc(this.images[index]);
+ this.$["image" + index].setScale(this.defaultScale);
+ this.$["image" + index].setDisableZoom(this.disableZoom);
+ }
+ }
+ }
+ return this.$["image" + index];
+ },
+ setImages: function(inImages) {
+ // always invoke imagesChanged because this is an array property
+ // which might otherwise seem to be the same object
+ this.setPropertyValue("images", inImages, "imagesChanged");
+ },
+ imagesChanged: function() {
+ this.initContainers();
+ this.loadNearby();
+ },
+ indexChanged: function() {
+ this.loadNearby();
+ if(this.lowMemory) {
+ this.cleanupMemory();
+ }
+ this.inherited(arguments);
+ },
+ transitionStart: function(inSender, inEvent) {
+ if(inEvent.fromIndex==inEvent.toIndex)
+ return true; //prevent from bubbling if there's no change
+ },
+ transitionFinish: function(inSender, inEvent) {
+ this.loadNearby();
+ if(this.lowMemory) {
+ this.cleanupMemory();
+ }
+ },
+ //* @public
+ //* Returns the currently displayed ImageView.
+ getActiveImage: function() {
+ return this.getImageByIndex(this.index);
+ },
+ //* Returns the ImageView with the specified index.
+ getImageByIndex: function(index) {
+ return this.$["image" + index] || this.loadImageView(index);
+ },
+ /**
+ Destroys any ImageView objects that are not in the immediate viewing
+ area (i.e., the currently active image and the first image on either
+ side of it) to free up memory. If you set the Image Carousel's
+ _lowMemory_ property to true, this function will be called automatically
+ as needed.
+ */
+ cleanupMemory: function() {
+ var buffer = getBufferRange();
+ for(var i=0; i<this.images.length; i++) {
+ if(enyo.indexOf(i, buffer) ===-1) {
+ if(this.$["image" + i]) {
+ this.$["image" + i].destroy();
+ }
+ }
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutimageviewsourceImageViewjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageView.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageView.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageView.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,379 @@
</span><ins>+/**
+ _enyo.ImageView_ is a control that displays an image at a given scaling
+ factor, with enhanced support for double-tap/double-click to zoom, panning,
+ mousewheel zooming and pinch-zoom (on touchscreen devices that support it).
+
+ {kind: "ImageView", src: "assets/globe.jpg", scale: "auto",
+ style: "width:500px; height:400px;"}
+
+ The _onload_ and _onerror_ events bubble up from the underlying image
+ element and an _onZoom_ event is triggered when the user changes the zoom
+ level of the image.
+
+ If you wish, you may add <a href="#enyo.ScrollThumb">enyo.ScrollThumb</a>
+ indicators, disable zoom animation, allow panning overscroll (with a
+ bounce-back effect), and control the propagation of drag events, all via
+ boolean properties.
+
+ Note that it's best to specify a size for the ImageView in order to avoid
+ complications.
+*/
+
+enyo.kind({
+ name: "enyo.ImageView",
+ kind: enyo.Scroller,
+ /**
+ If true, allows for overscrolling during panning, with a bounce-back
+ effect. (Defaults to false.)
+ */
+ touchOverscroll: false,
+ /**
+ If true, a ScrollThumb is used to indicate scroll position/bounds.
+ (Defaults to false.)
+ */
+ thumb: false,
+ /**
+ If true (the default), the zoom action triggered by a double-tap (or
+ double-click) will be animated.
+ */
+ animate: true,
+ /**
+ If true (the default), allows propagation of vertical drag events when
+ already at the top or bottom of the pannable area.
+ */
+ verticalDragPropagation: true,
+ /**
+ If true (the default), allows propagation of horizontal drag events when
+ already at the left or right edge of the pannable area.
+ */
+ horizontalDragPropagation: true,
+ published: {
+ /**
+ The scale at which the image should be displayed. It may be any
+ positive numeric value or one of the following key words (which will
+ be resolved to a value dynamically):
+
+ * "auto": Fits the image to the size of the ImageView
+ * "width": Fits the image the width of the ImageView
+ * "height": Fits the image to the height of the ImageView
+ * "fit": Fits the image to the height and width of the ImageView.
+ Overflow of the larger dimension is cropped and the image is centered
+ on this axis
+ */
+ scale: "auto",
+ //* Disables the zoom functionality
+ disableZoom: false,
+ //* The file path of the image to be displayed
+ src: undefined
+ },
+ events: {
+ /**
+ Fires whenever the user adjusts the zoom of the image, via
+ double-tap/double-click, mousewheel, or pinch-zoom.
+
+ _inEvent.scale_ contains the new scaling factor for the image.
+ */
+ onZoom:""
+ },
+ //* @protected
+ touch: true,
+ preventDragPropagation: false,
+ handlers: {
+ ondragstart: "dragPropagation"
+ },
+ components:[
+ {name: "animator", kind: "Animator", onStep: "zoomAnimationStep", onEnd: "zoomAnimationEnd"},
+ {name:"viewport", style: "overflow:hidden;min-height:100%;min-width:100%;", classes: "enyo-fit",
+ ongesturechange: "gestureTransform", ongestureend: "saveState", ontap: "singleTap",
+ ondblclick: "doubleClick", onmousewheel: "mousewheel",
+ components: [
+ {kind:"Image", ondown: "down"}
+ ]
+ }
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.canTransform = enyo.dom.canTransform();
+ if(!this.canTransform) {
+ this.$.image.applyStyle("position", "relative");
+ }
+ this.canAccelerate = enyo.dom.canAccelerate();
+ //offscreen buffer image to get initial image dimensions
+ //before displaying a scaled down image that can fit in the container
+ this.bufferImage = new Image();
+ this.bufferImage.onload = enyo.bind(this, "imageLoaded");
+ this.bufferImage.onerror = enyo.bind(this, "imageError");
+ this.srcChanged();
+ // For image view, disable drags during gesture (to fix flicker: ENYO-1208)
+ this.getStrategy().setDragDuringGesture(false);
+ // Needed to kickoff pin redrawing (otherwise they wont' redraw on intitial scroll)
+ if(this.getStrategy().$.scrollMath) {
+ this.getStrategy().$.scrollMath.start();
+ }
+ },
+ down: function(inSender, inEvent) {
+ // Fix to prevent image drag in Firefox
+ inEvent.preventDefault();
+ },
+ dragPropagation: function(inSender, inEvent) {
+ // Propagate drag events at the edges of the image as desired by the
+ // verticalDragPropagation and horizontalDragPropagation properties
+ var bounds = this.getStrategy().getScrollBounds();
+ var verticalEdge = ((bounds.top===0 && inEvent.dy>0) || (bounds.top>=bounds.maxTop-2 && inEvent.dy<0));
+ var horizontalEdge = ((bounds.left===0 && inEvent.dx>0) || (bounds.left>=bounds.maxLeft-2 && inEvent.dx<0));
+ return !((verticalEdge && this.verticalDragPropagation) || (horizontalEdge && this.horizontalDragPropagation));
+ },
+ mousewheel: function(inSender, inEvent) {
+ inEvent.pageX |= (inEvent.clientX + inEvent.target.scrollLeft);
+ inEvent.pageY |= (inEvent.clientY + inEvent.target.scrollTop);
+ var zoomInc = (this.maxScale - this.minScale)/10;
+ var oldScale = this.scale;
+ if((inEvent.wheelDelta > 0) || (inEvent.detail < 0)) { //zoom in
+ this.scale = this.limitScale(this.scale + zoomInc);
+ } else if((inEvent.wheelDelta < 0) || (inEvent.detail > 0)) { //zoom out
+ this.scale = this.limitScale(this.scale - zoomInc);
+ }
+ this.eventPt = this.calcEventLocation(inEvent);
+ this.transformImage(this.scale);
+ if(oldScale != this.scale) {
+ this.doZoom({scale:this.scale});
+ }
+ this.ratioX = this.ratioY = null;
+ // Prevent default scroll wheel action and prevent event from bubbling up to to touch scroller
+ inEvent.preventDefault();
+ return true;
+ },
+ srcChanged: function() {
+ if(this.src && this.src.length>0 && this.bufferImage && this.src!=this.bufferImage.src) {
+ this.bufferImage.src = this.src;
+ }
+ },
+ imageLoaded: function(inEvent) {
+ this.originalWidth = this.bufferImage.width;
+ this.originalHeight = this.bufferImage.height;
+
+ //scale to fit before setting src, so unscaled image isn't visible
+ this.scaleChanged();
+ this.$.image.setSrc(this.bufferImage.src);
+
+ //Needed to ensure scroller contents height/width is calculated correctly when contents use enyo-fit
+ enyo.dom.transformValue(this.getStrategy().$.client, "translate3d", "0px, 0px, 0");
+
+ this.positionClientControls(this.scale);
+ this.alignImage();
+ },
+ resizeHandler: function() {
+ this.inherited(arguments);
+ // Once we've loaded the image, adjust the min/max scale anytime we resize
+ if (this.$.image.src) {
+ this.scaleChanged();
+ }
+ },
+ scaleChanged: function() {
+ var containerNode = this.hasNode();
+ if(containerNode) {
+ this.containerWidth = containerNode.clientWidth;
+ this.containerHeight = containerNode.clientHeight;
+ var widthScale = this.containerWidth / this.originalWidth;
+ var heightScale = this.containerHeight / this.originalHeight;
+ this.minScale = Math.min(widthScale, heightScale);
+ this.maxScale = (this.minScale*3 < 1) ? 1 : this.minScale*3;
+ //resolve any keyword scale values to solid numeric values
+ if(this.scale == "auto") {
+ this.scale = this.minScale;
+ } else if(this.scale == "width") {
+ this.scale = widthScale;
+ } else if(this.scale == "height") {
+ this.scale = heightScale;
+ } else if(this.scale == "fit") {
+ this.fitAlignment = "center";
+ this.scale = Math.max(widthScale, heightScale);
+ } else {
+ this.maxScale = Math.max(this.maxScale, this.scale);
+ this.scale = this.limitScale(this.scale);
+ }
+ }
+ this.eventPt = this.calcEventLocation();
+ this.transformImage(this.scale);
+ },
+ imageError: function(inEvent) {
+ enyo.error("Error loading image: " + this.src);
+ //bubble up the error event
+ this.bubble("onerror", inEvent);
+ },
+ alignImage: function() {
+ if (this.fitAlignment && this.fitAlignment === "center") {
+ var sb = this.getScrollBounds();
+ this.setScrollLeft( sb.maxLeft / 2);
+ this.setScrollTop( sb.maxTop / 2);
+ }
+ },
+ gestureTransform: function(inSender, inEvent) {
+ this.eventPt = this.calcEventLocation(inEvent);
+ this.transformImage(this.limitScale(this.scale * inEvent.scale));
+ },
+ calcEventLocation: function(inEvent) {
+ //determine the target coordinates on the imageview from an event
+ var eventPt = {x: 0, y:0};
+ if(inEvent && this.hasNode()) {
+ var rect = this.node.getBoundingClientRect();
+ eventPt.x = Math.round((inEvent.pageX - rect.left) - this.imageBounds.x);
+ eventPt.x = Math.max(0, Math.min(this.imageBounds.width, eventPt.x));
+ eventPt.y = Math.round((inEvent.pageY - rect.top) - this.imageBounds.y);
+ eventPt.y = Math.max(0, Math.min(this.imageBounds.height, eventPt.y));
+ }
+ return eventPt;
+ },
+ transformImage: function(scale) {
+ this.tapped = false;
+
+ var prevBounds = this.imageBounds || this.innerImageBounds(scale);
+ this.imageBounds = this.innerImageBounds(scale);
+
+ //style cursor if needed to indicate the image is movable
+ if(this.scale>this.minScale) {
+ this.$.viewport.applyStyle("cursor", "move");
+ } else {
+ this.$.viewport.applyStyle("cursor", null);
+ }
+ this.$.viewport.setBounds({width: this.imageBounds.width + "px", height: this.imageBounds.height + "px"});
+
+ //determine the exact ratio where on the image was tapped
+ this.ratioX = this.ratioX || (this.eventPt.x + this.getScrollLeft()) / prevBounds.width;
+ this.ratioY = this.ratioY || (this.eventPt.y + this.getScrollTop()) / prevBounds.height;
+ var scrollLeft, scrollTop;
+ if(this.$.animator.ratioLock) { //locked for smartzoom
+ scrollLeft = (this.$.animator.ratioLock.x * this.imageBounds.width) - (this.containerWidth / 2);
+ scrollTop = (this.$.animator.ratioLock.y * this.imageBounds.height) - (this.containerHeight / 2);
+ } else {
+ scrollLeft = (this.ratioX * this.imageBounds.width) - this.eventPt.x;
+ scrollTop = (this.ratioY * this.imageBounds.height) - this.eventPt.y;
+ }
+ scrollLeft = Math.max(0, Math.min((this.imageBounds.width - this.containerWidth), scrollLeft));
+ scrollTop = Math.max(0, Math.min((this.imageBounds.height - this.containerHeight), scrollTop));
+
+ if(this.canTransform) {
+ var params = {scale: scale};
+ // translate needs to be first, or scale and rotation will not be in the correct spot
+ if(this.canAccelerate) {
+ //translate3d rounded values to avoid distortion; ref: http://martinkool.com/post/27618832225/beware-of-half-pixels-in-css
+ params = enyo.mixin({translate3d: Math.round(this.imageBounds.left) + "px, " + Math.round(this.imageBounds.top) + "px, 0px"}, params);
+ } else {
+ params = enyo.mixin({translate: this.imageBounds.left + "px, " + this.imageBounds.top + "px"}, params);
+ }
+ enyo.dom.transform(this.$.image, params);
+ } else { //pretty much just IE8
+ //use top/left and width/height to adjust
+ this.$.image.setBounds({width: this.imageBounds.width + "px", height: this.imageBounds.height + "px",
+ left:this.imageBounds.left + "px", top:this.imageBounds.top + "px"});
+ }
+
+ //adjust scroller to new position that keeps ratio with the new image size
+ this.setScrollLeft(scrollLeft);
+ this.setScrollTop(scrollTop);
+
+ this.positionClientControls(scale);
+
+ //this.stabilize();
+ },
+ limitScale: function(scale) {
+ if(this.disableZoom) {
+ scale = this.scale;
+ } else if(scale > this.maxScale) {
+ scale = this.maxScale;
+ } else if(scale < this.minScale) {
+ scale = this.minScale;
+ }
+ return scale;
+ },
+ innerImageBounds: function(scale) {
+ var width = this.originalWidth * scale;
+ var height = this.originalHeight * scale;
+ var offset = {x:0, y:0, transX:0, transY:0};
+ if(width<this.containerWidth) {
+ offset.x += (this.containerWidth - width)/2;
+ }
+ if(height<this.containerHeight) {
+ offset.y += (this.containerHeight - height)/2;
+ }
+ if(this.canTransform) { //adjust for the css translate, which doesn't alter image offsetWidth and offsetHeight
+ offset.transX -= (this.originalWidth - width)/2;
+ offset.transY -= (this.originalHeight - height)/2;
+ }
+ return {left:offset.x + offset.transX, top:offset.y + offset.transY, width:width, height:height, x:offset.x, y:offset.y};
+ },
+ saveState: function(inSender, inEvent) {
+ var oldScale = this.scale;
+ this.scale *= inEvent.scale;
+ this.scale = this.limitScale(this.scale);
+ if(oldScale != this.scale) {
+ this.doZoom({scale:this.scale});
+ }
+ this.ratioX = this.ratioY = null;
+ },
+ doubleClick: function(inSender, inEvent) {
+ //IE 8 fix; dblclick fires rather than multiple successive click events
+ if(enyo.platform.ie==8) {
+ this.tapped = true;
+ //normalize event
+ inEvent.pageX = inEvent.clientX + inEvent.target.scrollLeft;
+ inEvent.pageY = inEvent.clientY + inEvent.target.scrollTop;
+ this.singleTap(inSender, inEvent);
+ inEvent.preventDefault();
+ }
+ },
+ singleTap: function(inSender, inEvent) {
+ setTimeout(enyo.bind(this, function() {
+ this.tapped = false;
+ }), 300);
+ if(this.tapped) { //dbltap
+ this.tapped = false;
+ this.smartZoom(inSender, inEvent);
+ } else {
+ this.tapped = true;
+ }
+ },
+ smartZoom: function(inSender, inEvent) {
+ var containerNode = this.hasNode();
+ var imgNode = this.$.image.hasNode();
+ if(containerNode && imgNode && this.hasNode() && !this.disableZoom) {
+ var prevScale = this.scale;
+ if(this.scale!=this.minScale) { //zoom out
+ this.scale = this.minScale;
+ } else { //zoom in
+ this.scale = this.maxScale;
+ }
+ this.eventPt = this.calcEventLocation(inEvent);
+ if(this.animate) {
+ //lock ratio position of event, and animate the scale change
+ var ratioLock = {
+ x: ((this.eventPt.x + this.getScrollLeft()) / this.imageBounds.width),
+ y: ((this.eventPt.y + this.getScrollTop()) / this.imageBounds.height)
+ };
+ this.$.animator.play({
+ duration:350,
+ ratioLock: ratioLock,
+ baseScale:prevScale,
+ deltaScale:this.scale - prevScale
+ });
+ } else {
+ this.transformImage(this.scale);
+ this.doZoom({scale:this.scale});
+ }
+ }
+ },
+ zoomAnimationStep: function(inSender, inEvent) {
+ var currScale = this.$.animator.baseScale + (this.$.animator.deltaScale * this.$.animator.value);
+ this.transformImage(currScale);
+ },
+ zoomAnimationEnd: function(inSender, inEvent) {
+ this.doZoom({scale:this.scale});
+ this.$.animator.ratioLock = undefined;
+ },
+ positionClientControls: function(scale) {
+ this.waterfallDown("onPositionPin", {
+ scale: scale,
+ bounds: this.imageBounds
+ });
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutimageviewsourceImageViewPincss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageViewPin.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageViewPin.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageViewPin.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+
+.pinDebug {
+ background:yellow;
+ border:1px solid yellow;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutimageviewsourceImageViewPinjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageViewPin.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageViewPin.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/imageview/source/ImageViewPin.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,123 @@
</span><ins>+/**
+ _enyo.ImageViewPin_ is a control that can be used to display non-zooming
+ content inside of a zoomable _enyo.ImageView_ control. The _anchor_ and
+ _position_ properties can be used to position both the ImageViewPin and its
+ content in a specific location inside of the ImageView.
+*/
+enyo.kind({
+ name: "enyo.ImageViewPin",
+ kind: "enyo.Control",
+ published: {
+ /**
+ If true, the anchor point for this pin will be highlighted in yellow,
+ which can be useful for debugging. Defaults to false.
+ */
+ highlightAnchorPoint: false,
+ /**
+ The coordinates at which this control should be anchored inside
+ of the parent ImageView control. This position is relative to the
+ ImageView control's original size. Works like standard CSS positioning,
+ and accepts both px and percentage values. Defaults to _{top: 0px,
+ left: 0px}_.
+
+ * top: distance from the parent's top edge
+ * bottom: distance from the parent's bottom edge (overrides top)
+ * left: distance from the parent's left edge
+ * right: distance from the parennt's right edge (overrides left)
+ */
+ anchor: {
+ top: 0,
+ left: 0
+ },
+ /**
+ The coordinates at which the contents of this control should be
+ positioned relative to the ImageViewPin itself. Works like standard
+ CSS positioning. Only accepts px values. Defaults to _{top: 0px,
+ left: 0px}_.
+
+ * top: distance from the ImageViewPin's top edge
+ * bottom: distance from the ImageViewPin's bottom edge
+ * left: distance from the ImageViewPin's left edge
+ * right: distance from the ImageViewPin's right edge
+ */
+ position: {
+ top: 0,
+ left: 0
+ }
+ },
+ //* @protected
+ style: "position:absolute;z-index:1000;width:0px;height:0px;",
+ handlers: {
+ onPositionPin: "reAnchor"
+ },
+ create: function() {
+ this.inherited(arguments);
+ this.styleClientControls();
+ this.positionClientControls();
+ this.highlightAnchorPointChanged();
+ this.anchorChanged();
+ },
+ // Absolutely position to client controls
+ styleClientControls: function() {
+ var controls = this.getClientControls();
+ for(var i=0;i<controls.length;i++) {
+ controls[i].applyStyle("position","absolute");
+ }
+ },
+ // Apply specified positioning to client controls
+ positionClientControls: function() {
+ var controls = this.getClientControls();
+ for(var i=0;i<controls.length;i++) {
+ for(var p in this.position) {
+ controls[i].applyStyle(p, this.position[p]+"px");
+ }
+ }
+ },
+ // Update styling on anchor point
+ highlightAnchorPointChanged: function() {
+ this.addRemoveClass("pinDebug", this.highlightAnchorPoint);
+ },
+ // Create coords{} object for each anchor containing value and units
+ anchorChanged: function() {
+ var coords = null, a = null;
+ for(a in this.anchor) {
+ coords = this.anchor[a].toString().match(/^(\d+(?:\.\d+)?)(.*)$/);
+ if(!coords) {
+ continue;
+ }
+ this.anchor[a+"Coords"] = {
+ value: coords[1],
+ units: coords[2] || "px"
+ };
+ }
+ },
+ /*
+ Apply positioning to ImageViewPin specified in this.anchor{}.
+ Called anytime the parent ImageView is rescaled. If right/bottom
+ are specified, they override top/left.
+ */
+ reAnchor: function(inSender, inEvent) {
+ var scale = inEvent.scale;
+ var bounds = inEvent.bounds;
+ var left = (this.anchor.right)
+ // Right
+ ? (this.anchor.rightCoords.units == "px")
+ ? (bounds.width + bounds.x - this.anchor.rightCoords.value*scale)
+ : (bounds.width*(100-this.anchor.rightCoords.value)/100 + bounds.x)
+ // Left
+ : (this.anchor.leftCoords.units == "px")
+ ? (this.anchor.leftCoords.value*scale + bounds.x)
+ : (bounds.width*this.anchor.leftCoords.value/100 + bounds.x);
+ var top = (this.anchor.bottom)
+ // Bottom
+ ? (this.anchor.bottomCoords.units == "px")
+ ? (bounds.height + bounds.y - this.anchor.bottomCoords.value*scale)
+ : (bounds.height*(100-this.anchor.bottomCoords.value)/100 + bounds.y)
+ // Top
+ : (this.anchor.topCoords.units == "px")
+ ? (this.anchor.topCoords.value*scale + bounds.y)
+ : (bounds.height*this.anchor.topCoords.value/100 + bounds.y);
+ this.applyStyle("left", left+"px");
+ this.applyStyle("top", top+"px");
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutimageviewsourcepackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/imageview/source/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/imageview/source/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/imageview/source/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+enyo.depends(
+ "ImageViewPin.js",
+ "ImageViewPin.css",
+ "ImageView.js",
+ "ImageCarousel.js"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistpackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+enyo.depends(
+ "source/"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesFlyweightRepeaterSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+.flyweight-repeater-sample {
+ background-color: gray;
+ position: relative;
+}
+.flyweight-repeater-sample-list {
+ position: relative;
+ width: 100%;
+ margin: auto;
+ background-color: #eee;
+}
+.flyweight-repeater-sample-item {
+ border: 1px solid silver;
+ padding: 18px;
+ font-size: 18px;
+ font-weight: bold;
+}
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.css
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesFlyweightRepeaterSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>FlyweightRepeater Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="FlyweightRepeaterSample.css" rel="stylesheet">
+ <script src="NameGenerator.js" type="text/javascript"></script>
+ <script src="FlyweightRepeaterSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.FlyweightRepeaterSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.html
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesFlyweightRepeaterSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.FlyweightRepeaterSample",
+ kind: "FittableRows",
+ classes: "flyweight-repeater-sample enyo-fit onyx",
+ components: [
+ {kind: "onyx.Toolbar", components: [
+ {content: "FlyweightRepeater Result"}
+ ]},
+ {name:"result", style:"padding:12px; font-size: 20px;", content: "Nothing selected yet."},
+ {kind: "enyo.Scroller", fit: true, components: [
+ {name:"repeater", kind:"enyo.FlyweightRepeater", classes:"flyweight-repeater-sample-list", count: 26, onSetupItem: "setupItem", components: [
+ {name: "item", classes:"flyweight-repeater-sample-item"}
+ ]}
+ ]}
+ ],
+ handlers: {
+ onSelect: "itemSelected"
+ },
+ people: [
+ {name: "Andrew"},
+ {name: "Betty"},
+ {name: "Christopher"},
+ {name: "Donna"},
+ {name: "Ephraim"},
+ {name: "Frankie"},
+ {name: "Gerald"},
+ {name: "Heather"},
+ {name: "Ingred"},
+ {name: "Jack"},
+ {name: "Kevin"},
+ {name: "Lucy"},
+ {name: "Matthew"},
+ {name: "Noreen"},
+ {name: "Oscar"},
+ {name: "Pedro"},
+ {name: "Quentin"},
+ {name: "Ralph"},
+ {name: "Steven"},
+ {name: "Tracy"},
+ {name: "Uma"},
+ {name: "Victor"},
+ {name: "Wendy"},
+ {name: "Xin"},
+ {name: "Yulia"},
+ {name: "Zoltan"}
+ ],
+ setupItem: function(inSender, inEvent) {
+ var index = inEvent.index;
+ this.$.item.setContent((index+1) + ". " + this.people[index].name);
+ this.$.item.applyStyle("background", (inEvent.selected? "dodgerblue":"lightgray"));
+ },
+ itemSelected: function(inSender, inEvent) {
+ var index = inEvent.index;
+ var count = inEvent.flyweight.count;
+ if(index>=0 && index<count){
+ this.$.result.setContent(" [" + (index+1) + ". " + this.people[index].name + "] is selected");
+ }
+ }
+});
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/FlyweightRepeaterSample.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesListAroundSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListAroundSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListAroundSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListAroundSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+.list-sample-around {
+ background: url(assets/bg.png);
+}
+/* item */
+.list-sample-around-item {
+ height: 100px;
+ border-top: 1px solid silver;
+ padding: 12px 16px;
+ background-color: #333333;
+}
+.list-sample-around-item-selected {
+ background: #226B9A url(assets/item-hilite.png) repeat-x bottom;
+}
+.list-sample-around-item > * {
+ display: inline-block;
+ vertical-align: middle;
+}
+.list-sample-around-avatar {
+ width: 32px;
+ height: 32px;
+ padding-right: 10px;
+}
+.list-sample-around-name {
+ font-size: 16px;
+ font-weight: bold;
+ color: white;
+}
+.list-sample-around-description {
+ font-size: 12px;
+ color: silver;
+}
+.list-sample-around-remove-button {
+ float: right;
+ display: none;
+}
+/* divider */
+.list-sample-around-divider {
+ background-color: #666;
+ font-size: 14px;
+ font-weight: bold;
+ padding: 8px 14px;
+}
+/* popup */
+.list-sample-around-popup {
+ width: 280px;
+}
+.list-sample-around-popup > * {
+ display: block;
+ margin: 10px 10px;
+}
+.list-sample-around-populate-button {
+ float: right;
+ margin-top: 25px;
+}
+.list-sample-around-label {
+ display: inline-block;
+ width: 120px;
+ padding-right: 10px;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListAroundSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListAroundSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListAroundSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListAroundSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>AroundList Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="ListAroundSample.css" rel="stylesheet">
+ <script src="NameGenerator.js" type="text/javascript"></script>
+ <script src="ListAroundSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.ListAroundSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListAroundSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListAroundSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListAroundSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListAroundSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,211 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.ListAroundSample",
+ kind: "FittableRows",
+ classes: "enyo-fit enyo-unselectable",
+ components: [
+ {name: "list", kind: "AroundList", classes: "list-sample-around", fit: true, multiSelect: true, onSetupItem: "setupItem", aboveComponents: [
+ {kind: "onyx.Toolbar", layoutKind: "FittableColumnsLayout", components: [
+ {kind: "onyx.InputDecorator", fit: true, noStretch: true, layoutKind: "FittableColumnsLayout", components: [
+ {kind: "onyx.Input", placeholder: "Search...", fit: true, oninput: "searchInputChange"},
+ {kind: "Image", src: "assets/search-input-search.png", style: "height: 20px; width: 20px;"}
+ ]}
+ ]}
+ ], components: [
+ {name: "divider", classes: "list-sample-around-divider"},
+ {name: "item", kind: "AroundListContactItem", classes: "list-sample-around-item enyo-border-box", onRemove: "removeTap"}
+ ]},
+ {name: "popup", kind: "onyx.Popup", modal: true, centered: true, classes: "list-sample-around-popup", components: [
+ {components: [
+ {content: "count:", classes: "list-sample-around-label"},
+ {kind: "onyx.InputDecorator", components: [
+ {name: "countInput", kind: "onyx.Input", style: "width: 80px", value: 100}
+ ]}
+ ]},
+ {components: [
+ {content: "rowsPerPage:", classes: "list-sample-around-label"},
+ {kind: "onyx.InputDecorator", components: [
+ {name: "rowsPerPageInput", kind: "onyx.Input", style: "width: 80px", value: 50}
+ ]}
+ ]},
+ {components: [
+ {content: "hide divider:", classes: "list-sample-around-label"},
+ {name: "hideDividerCheckbox", kind: "onyx.Checkbox"}
+ ]},
+ {components: [
+ {kind: "onyx.Button", content: "populate list", classes: "list-sample-around-populate-button", ontap: "populateList"}
+ ]}
+ ]}
+ ],
+ rendered: function() {
+ this.inherited(arguments);
+ this.populateList();
+ },
+ setupItem: function(inSender, inEvent) {
+ var i = inEvent.index;
+ var data = this.filter ? this.filtered : this.db;
+ var item = data[i];
+ // content
+ this.$.item.setContact(item);
+ // selection
+ this.$.item.setSelected(inSender.isSelected(i));
+ // divider
+ if (!this.hideDivider) {
+ var d = item.name[0];
+ var prev = data[i-1];
+ var showd = d != (prev && prev.name[0]);
+ this.$.divider.setContent(d);
+ this.$.divider.canGenerate = showd;
+ this.$.item.applyStyle("border-top", showd ? "none" : null);
+ }
+ },
+ refreshList: function() {
+ if (this.filter) {
+ this.filtered = this.generateFilteredData(this.filter);
+ this.$.list.setCount(this.filtered.length);
+ } else {
+ this.$.list.setCount(this.db.length);
+ }
+ this.$.list.refresh();
+ },
+ addItem: function() {
+ var item = this.generateItem(enyo.cap(this.$.newContactInput.getValue()));
+ var i = 0;
+ for (var di; (di=this.db[i]); i++) {
+ if (di.name > item.name) {
+ this.db.splice(i, 0, item);
+ break;
+ }
+ }
+ this.refreshList();
+ this.$.list.scrollToRow(i);
+ },
+ removeItem: function(inIndex) {
+ this._removeItem(inIndex);
+ this.refreshList();
+ this.$.list.getSelection().deselect(inIndex);
+ },
+ _removeItem: function(inIndex) {
+ var i = this.filter ? this.filtered[inIndex].dbIndex : inIndex;
+ this.db.splice(i, 1);
+ },
+ removeTap: function(inSender, inEvent) {
+ this.removeItem(inEvent.index);
+ return true;
+ },
+ populateList: function() {
+ this.$.popup.hide();
+ this.createDb(this.$.countInput.getValue());
+ this.$.list.setCount(this.db.length);
+ this.$.list.setRowsPerPage(this.$.rowsPerPageInput.getValue());
+ //
+ this.hideDivider = this.$.hideDividerCheckbox.getValue();
+ this.$.divider.canGenerate = !this.hideDivider;
+ //
+ this.$.list.reset();
+ this.$.list.scrollToContentStart();
+ },
+ createDb: function(inCount) {
+ this.db = [];
+ for (var i=0; i<inCount; i++) {
+ this.db.push(this.generateItem(makeName(4, 6) + " " + makeName(5, 10)));
+ }
+ this.sortDb();
+ },
+ generateItem: function(inName) {
+ return {
+ name: inName,
+ avatar: "assets/avatars/" + avatars[enyo.irand(avatars.length)],
+ title: titles[enyo.irand(titles.length)]
+ };
+ },
+ sortDb: function() {
+ this.db.sort(function(a, b) {
+ if (a.name < b.name) return -1;
+ else if (a.name > b.name) return 1;
+ else return 0;
+ });
+ },
+ showSetupPopup: function() {
+ this.$.popup.show();
+ },
+ searchInputChange: function(inSender) {
+ enyo.job(this.id + ":search", enyo.bind(this, "filterList", inSender.getValue()), 200);
+ },
+ filterList: function(inFilter) {
+ if (inFilter != this.filter) {
+ this.filter = inFilter;
+ this.filtered = this.generateFilteredData(inFilter);
+ this.$.list.setCount(this.filtered.length);
+ this.$.list.reset();
+ }
+ },
+ generateFilteredData: function(inFilter) {
+ var re = new RegExp("^" + inFilter, "i");
+ var r = [];
+ for (var i=0, d; (d=this.db[i]); i++) {
+ if (d.name.match(re)) {
+ d.dbIndex = i;
+ r.push(d);
+ }
+ }
+ return r;
+ }
+});
+
+var avatars = [
+ "angel.png",
+ "astrologer.png",
+ "athlete.png",
+ "baby.png",
+ "clown.png",
+ "devil.png",
+ "doctor.png",
+ "dude.png",
+ "dude2.png",
+ "dude3.png",
+ "dude4.png",
+ "dude5.png",
+ "dude6.png"
+];
+var titles = [
+ "Regional Data Producer",
+ "Internal Markets Administrator",
+ "Central Solutions Producer",
+ "Dynamic Program Executive",
+ "Direct Configuration Executive",
+ "International Marketing Assistant",
+ "District Research Consultant",
+ "Lead Intranet Coordinator",
+ "Central Accountability Director",
+ "Product Web Assistant"
+];
+
+// It's convenient to create a kind for the item we'll render in the contacts list.
+enyo.kind({
+ name: "AroundListContactItem",
+ events: {
+ onRemove: ""
+ },
+ components: [
+ {name: "avatar", kind: "Image", classes: "list-sample-around-avatar"},
+ {components: [
+ {name: "name", classes: "list-sample-around-name"},
+ {name: "title", classes: "list-sample-around-description"},
+ {content: "(415) 711-1234", classes: "list-sample-around-description"}
+ ]},
+ {name: "remove", kind: "onyx.IconButton", classes: "list-sample-around-remove-button", src: "assets/remove-icon.png", ontap: "removeTap"}
+ ],
+ setContact: function(inContact) {
+ this.$.name.setContent(inContact.name);
+ this.$.avatar.setSrc(inContact.avatar);
+ this.$.title.setContent(inContact.title);
+ },
+ setSelected: function(inSelected) {
+ this.addRemoveClass("list-sample-around-item-selected", inSelected);
+ this.$.remove.applyStyle("display", inSelected ? "inline-block" : "none");
+ },
+ removeTap: function(inSender, inEvent) {
+ this.doRemove(inEvent);
+ return true;
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListBasicSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListBasicSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListBasicSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListBasicSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+.list-sample {
+ background-color: gray;
+}
+.list-sample-list {
+ width: 50%;
+ min-width: 300px;
+ max-width: 600px;
+ margin: auto;
+ background-color: #eee;
+}
+.list-sample-item {
+ border: 1px solid silver;
+ padding: 18px;
+ font-size: 18px;
+ font-weight: bold;
+}
+.list-sample-index {
+ float: right;
+ font-size: 16px;
+ font-weight: normal;
+}
+.list-sample-selected {
+ background-color: #c4e3fe;
+}
+/* needed to make onyx-highlight more specific for highlighting to work */
+.onyx-highlight.list-sample-selected {
+ background-color: #dedfdf;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListBasicSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListBasicSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListBasicSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListBasicSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Basic List Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="ListBasicSample.css" rel="stylesheet">
+ <script src="NameGenerator.js" type="text/javascript"></script>
+ <script src="ListBasicSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.ListBasicSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListBasicSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListBasicSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListBasicSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListBasicSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.ListBasicSample",
+ classes: "list-sample enyo-fit",
+ components: [
+ {name: "list", kind: "List", count: 20000, multiSelect: false, classes: "enyo-fit list-sample-list", onSetupItem: "setupItem", components: [
+ {name: "item", classes: "list-sample-item enyo-border-box", components: [
+ {name: "index", classes: "list-sample-index"},
+ {name: "name"}
+ ]}
+ ]}
+ ],
+ names: [],
+ setupItem: function(inSender, inEvent) {
+ // this is the row we're setting up
+ var i = inEvent.index;
+ // make some mock data if we have none for this row
+ if (!this.names[i]) {
+ this.names[i] = makeName(5, 10, '', '');
+ }
+ var n = this.names[i];
+ var ni = ("00000000" + i).slice(-7);
+ // apply selection style if inSender (the list) indicates that this row is selected.
+ this.$.item.addRemoveClass("list-sample-selected", inSender.isSelected(i));
+ this.$.name.setContent(n);
+ this.$.index.setContent(ni);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListContactsSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListContactsSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListContactsSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListContactsSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+.list-sample-contacts {
+ color: white;
+}
+.list-sample-contacts-list {
+ background: url(assets/bg.png);
+}
+/* item */
+.list-sample-contacts-item {
+ height: 100px;
+ border-top: 1px solid silver;
+ padding: 12px 16px;
+ background-color: #333333;
+}
+.list-sample-contacts-item-selected {
+ background: #226B9A url(assets/item-hilite.png) repeat-x bottom;
+}
+.list-sample-contacts-item > * {
+ display: inline-block;
+ vertical-align: middle;
+}
+.list-sample-contacts-avatar {
+ width: 32px;
+ height: 32px;
+ padding-right: 10px;
+}
+.list-sample-contacts-description {
+ font-size: 12px;
+ color: silver;
+}
+.list-sample-contacts-remove-button {
+ float: right;
+ display: none;
+}
+/* divider */
+.list-sample-contacts-divider {
+ background-color: #666;
+ font-size: 14px;
+ font-weight: bold;
+ padding: 8px 14px;
+}
+/* popup */
+.list-sample-contacts-popup {
+ width: 280px;
+}
+.list-sample-contacts-popup > * {
+ display: block;
+ margin: 10px 10px;
+}
+.list-sample-contacts-populate-button {
+ float: right;
+ margin-top: 25px;
+}
+.list-sample-contacts-label {
+ display: inline-block;
+ width: 120px;
+ padding-right: 10px;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListContactsSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListContactsSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListContactsSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListContactsSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Contacts List Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="ListContactsSample.css" rel="stylesheet">
+ <script src="NameGenerator.js" type="text/javascript"></script>
+ <script src="ListContactsSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.ListContactsSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListContactsSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListContactsSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListContactsSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListContactsSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,261 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.ListContactsSample",
+ kind: "FittableRows",
+ classes: "list-sample-contacts enyo-fit",
+ components: [
+ {kind: "onyx.MoreToolbar", layoutKind: "FittableColumnsLayout", style: "height: 55px;", components: [
+ {kind: "onyx.Button", content: "setup", ontap: "showSetupPopup"},
+ {kind: "onyx.InputDecorator", components: [
+ {name: "newContactInput", kind: "onyx.Input", value: "Frankie Fu"}
+ ]},
+ {kind: "onyx.Button", content: "new contact", ontap: "addItem"},
+ {fit: true},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "Search...", style: "width: 140px;", oninput: "searchInputChange"},
+ {kind: "Image", src: "assets/search-input-search.png", style: "width: 20px;"}
+ ]},
+ {kind: "onyx.Button", content: "remove selected", ontap: "removeSelected"}
+ ]},
+ {kind: "List", classes: "list-sample-contacts-list enyo-unselectable", fit: true, multiSelect: true,
+ onSetupItem: "setupItem", components: [
+ {name: "divider", classes: "list-sample-contacts-divider"},
+ {name: "item", kind: "ContactItem", classes: "list-sample-contacts-item enyo-border-box", onRemove: "removeTap"}
+ ]
+ },
+ {name: "popup", kind: "onyx.Popup", modal: true, centered: true, classes: "list-sample-contacts-popup", components: [
+ {components: [
+ {style: "display:inline-block", components:[
+ {content: "count:", classes: "list-sample-contacts-label"},
+ {name: "countOutput", style: "display:inline-block;", content: "200"}
+ ]},
+ {kind: "onyx.Slider", value: 4, onChanging: "countSliderChanging", onChange: "countSliderChanging"}
+ ]},
+ {components: [
+ {content: "rowsPerPage:", classes: "list-sample-contacts-label"},
+ {name: "rowsPerPageOutput", style: "display:inline-block;", content: "50"},
+ {kind: "onyx.Slider", value: 10, onChanging: "rowsSliderChanging", onChange: "rowsSliderChanging"}
+ ]},
+ {components: [
+ {content: "hide divider:", classes: "list-sample-contacts-label"},
+ {name: "hideDividerCheckbox", kind: "onyx.Checkbox"}
+ ]},
+ {components: [
+ {kind: "onyx.Button", content: "populate list", classes: "list-sample-contacts-populate-button", ontap: "populateList"}
+ ]}
+ ]}
+ ],
+ rendered: function() {
+ this.inherited(arguments);
+ this.populateList();
+ },
+ setupItem: function(inSender, inEvent) {
+ var i = inEvent.index;
+ var data = this.filter ? this.filtered : this.db;
+ var item = data[i];
+ // content
+ this.$.item.setContact(item);
+ // selection
+ this.$.item.setSelected(inSender.isSelected(i));
+ // divider
+ if (!this.hideDivider) {
+ var d = item.name[0];
+ var prev = data[i-1];
+ var showd = d != (prev && prev.name[0]);
+ this.$.divider.setContent(d);
+ this.$.divider.canGenerate = showd;
+ this.$.item.applyStyle("border-top", showd ? "none" : null);
+ }
+ },
+ refreshList: function() {
+ if (this.filter) {
+ this.filtered = this.generateFilteredData(this.filter);
+ this.$.list.setCount(this.filtered.length);
+ } else {
+ this.$.list.setCount(this.db.length);
+ }
+ this.$.list.refresh();
+ },
+ addItem: function() {
+ var item = this.generateItem(enyo.cap(this.$.newContactInput.getValue()));
+ var i = 0;
+ for (var di; (di=this.db[i]); i++) {
+ if (di.name > item.name) {
+ this.db.splice(i, 0, item);
+ break;
+ }
+ }
+ // if we hit end of for-loop, add to end of list
+ if (!di) {
+ this.db.push(item);
+ }
+ this.refreshList();
+ this.$.list.scrollToRow(i);
+ },
+ removeItem: function(inIndex) {
+ this._removeItem(inIndex);
+ this.$.list.getSelection().remove(inIndex);
+ this.refreshList();
+ },
+ _removeItem: function(inIndex) {
+ var i = this.filter ? this.filtered[inIndex].dbIndex : inIndex;
+ this.db.splice(i, 1);
+ },
+ removeTap: function(inSender, inEvent) {
+ this.removeItem(inEvent.index);
+ return true;
+ },
+ removeSelected: function() {
+ // get selected items, sort numerically in decending order
+ var selected = enyo.keys(this.$.list.getSelection().getSelected());
+ selected.sort(function(a,b) { return b-a; });
+ // remove items one-by-one, starting with last in the list
+ for (var i=0; i < selected.length; i++) {
+ this._removeItem(selected[i]);
+ }
+ // clear selection, since all selected items are now gone
+ this.$.list.getSelection().clear();
+ // re-render list in current position
+ this.refreshList();
+ },
+ populateList: function() {
+ this.$.popup.hide();
+ this.createDb(~~this.$.countOutput.getContent());
+ this.$.list.setCount(this.db.length);
+ this.$.list.setRowsPerPage(~~this.$.rowsPerPageOutput.getContent());
+ //
+ this.hideDivider = this.$.hideDividerCheckbox.getValue();
+ //this.$.divider.canGenerate = !this.hideDivider;
+ //
+ this.$.list.reset();
+ },
+ createDb: function(inCount) {
+ this.db = [];
+ for (var i=0; i<inCount; i++) {
+ this.db.push(this.generateItem(makeName(4, 6) + " " + makeName(5, 10)));
+ }
+ this.sortDb();
+ },
+ generateItem: function(inName) {
+ return {
+ name: inName,
+ avatar: "assets/avatars/" + avatars[enyo.irand(avatars.length)],
+ title: titles[enyo.irand(titles.length)],
+ importance: 0
+ };
+ },
+ sortDb: function() {
+ this.db.sort(function(a, b) {
+ if (a.name < b.name) return -1;
+ else if (a.name > b.name) return 1;
+ else return 0;
+ });
+ },
+ showSetupPopup: function() {
+ this.$.popup.show();
+ },
+ searchInputChange: function(inSender) {
+ enyo.job(this.id + ":search", enyo.bind(this, "filterList", inSender.getValue()), 200);
+ },
+ filterList: function(inFilter) {
+ if (inFilter != this.filter) {
+ this.filter = inFilter;
+ this.filtered = this.generateFilteredData(inFilter);
+ this.$.list.setCount(this.filtered.length);
+ this.$.list.reset();
+ }
+ },
+ generateFilteredData: function(inFilter) {
+ var re = new RegExp("^" + inFilter, "i");
+ var r = [];
+ for (var i=0, d; (d=this.db[i]); i++) {
+ if (d.name.match(re)) {
+ d.dbIndex = i;
+ r.push(d);
+ }
+ }
+ return r;
+ },
+ countSliderChanging: function(inSender, inEvent){
+ this.$.countOutput.setContent(Math.round(inSender.getValue()) * 50);
+ },
+ rowsSliderChanging: function(inSender, inEvent){
+ this.$.rowsPerPageOutput.setContent(Math.round(inSender.getValue()) * 5);
+ }
+});
+
+var avatars = [
+ "angel.png",
+ "astrologer.png",
+ "athlete.png",
+ "baby.png",
+ "clown.png",
+ "devil.png",
+ "doctor.png",
+ "dude.png",
+ "dude2.png",
+ "dude3.png",
+ "dude4.png",
+ "dude5.png",
+ "dude6.png"
+];
+var titles = [
+ "Regional Data Producer",
+ "Internal Markets Administrator",
+ "Central Solutions Producer",
+ "Dynamic Program Executive",
+ "Direct Configuration Executive",
+ "International Marketing Assistant",
+ "District Research Consultant",
+ "Lead Intranet Coordinator",
+ "Central Accountability Director",
+ "Product Web Assistant"
+];
+
+// It's convenient to create a kind for the item we'll render in the contacts list.
+enyo.kind({
+ name: "ContactItem",
+ events: {
+ onRemove: ""
+ },
+ published: {
+ importance: 0
+ },
+ components: [
+ {name: "avatar", kind: "Image", classes: "list-sample-contacts-avatar"},
+ {components: [
+ {name: "name"},
+ {name: "title", classes: "list-sample-contacts-description"},
+ {content: "(415) 711-1234", classes: "list-sample-contacts-description"}
+ ]},
+ {name: "remove", kind: "onyx.IconButton", classes: "list-sample-contacts-remove-button", src: "assets/remove-icon.png", ontap: "removeTap"}
+ ],
+ setContact: function(inContact) {
+ this.$.name.setContent(inContact.name);
+ this.$.avatar.setSrc(inContact.avatar);
+ this.$.title.setContent(inContact.title);
+ },
+ setSelected: function(inSelected) {
+ this.addRemoveClass("list-sample-contacts-item-selected", inSelected);
+ this.$.remove.applyStyle("display", inSelected ? "inline-block" : "gne");
+ },
+ renderImportance: function() {
+ switch(this.importance) {
+ case 0:
+ this.$.importance.setContent("not important");
+ break;
+ case -1:
+ this.$.importance.setContent("important");
+ break;
+ case -2:
+ this.$.importance.setContent("very important");
+ break;
+ default:
+ alert(this.importance+" - wowzer");
+ break;
+ }
+ },
+ removeTap: function(inSender, inEvent) {
+ this.doRemove(inEvent);
+ return true;
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListLanguagesSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListLanguagesSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListLanguagesSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListLanguagesSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+.list-sample-language {
+ color: white;
+}
+.list-sample-language-list {
+ background: url(assets/bg.png);
+}
+.list-sample-language-item {
+ height: 80px;
+ border-top: 1px solid #000;
+ padding: 12px 16px;
+ background-color: #333333;
+ position:relative;
+}
+.list-sample-language-list .rowNumberLabel {
+ position:absolute;
+ right:15px;
+ bottom: 10px;
+ font-size:12px;
+}
+.list-sample-language-list .itemLabel {
+ font-size:24px;
+ line-height:80px;
+ padding-left:30px;
+}
+.list-sample-language-list .serialLabel {
+ position:absolute;
+ right:80px;
+ bottom: 10px;
+ font-size:12px;
+}
+.list-sample-language-list .reorderDragger {
+ background:rgb(0,0,0);
+}
+.list-sample-language-list .swipeGreen {
+ background-color:rgb(0,160,40);
+}
+.list-sample-language-list h2 {
+ margin:0;
+ padding:0 0 0 20px;
+ font-size:24px;
+ line-height:100px;
+}
+.list-sample-language-list .dropButton {
+ width:90px;
+ height:60px;
+ position:absolute;
+ top:20px;
+ right:110px;
+}
+.list-sample-language-list .cancelButton {
+ width:90px;
+ height:60px;
+ position:absolute;
+ top:20px;
+ right:10px;
+}
+.list-sample-language-list .swipeTitle {
+ font-size:30px;
+ font-weight:bold;
+ text-align:center;
+ line-height:100px;
+ padding:0;
+ margin:0;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListLanguagesSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListLanguagesSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListLanguagesSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListLanguagesSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Contacts List Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="ListLanguagesSample.css" rel="stylesheet">
+ <script src="NameGenerator.js" type="text/javascript"></script>
+ <script src="ListLanguagesSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.ListLanguagesSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListLanguagesSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListLanguagesSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListLanguagesSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListLanguagesSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,160 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.ListLanguagesSample",
+ kind: "FittableRows",
+ classes: "list-sample-language enyo-fit",
+ data: [],
+ languages: {
+ English: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"],
+ Italian: ["Uno", "Due", "Tre", "Quattro", "Cinque", "Sei", "Sette", "Otto", "Nove", "Dieci"],
+ Spanish: ["Uno", "Dos", "Tres", "Cuatro", "Cinco", "Seis", "Siete", "Ocho", "Nueve", "Diez"],
+ German: ["Eins", "Zwei", "Drei", "Vier", "F\xFCnf", "Sechs", "Sieben", "Acht", "Neun", "Zehn"],
+ French: ["Un", "Deux", "Trois", "Quatre", "Cinq", "Six", "Sept", "Huit", "Neuf", "Dix"]
+ },
+ components: [
+ {kind: "onyx.MoreToolbar", layoutKind: "FittableColumnsLayout", style: "height: 55px;", components: [
+ {content: "Rows:"},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", value: "10", name: "numRows" }
+ ]},
+ {kind: "onyx.Button", content: "Repopulate", ontap: "populateList"}
+ ]},
+ {kind: "List", classes: "list-sample-language-list enyo-unselectable",
+ fit: true, multiSelect: true,
+ reorderable: true, centerReorderContainer: false,
+ enableSwipe: true,
+ onSetupItem: "setupItem",
+ onReorder: "listReorder",
+ onSetupReorderComponents: "setupReorderComponents",
+ // onSetupPinnedReorderComponents: "setupPinnedReorderComponents",
+ onSetupSwipeItem: "setupSwipeItem",
+ onSwipeComplete: "swipeComplete",
+ components: [
+ {name: "item", classes: "list-sample-language-item", components: [
+ {name: "text", classes: "itemLabel"},
+ {name: "rowNumber", classes: "rowNumberLabel"},
+ {name: "serial", classes: "serialLabel"}
+ ]}
+ ],
+ reorderComponents: [
+ {name: "reorderContent", classes: "enyo-fit reorderDragger", components: [
+ {name: "reorderTitle", tag: "h2", allowHtml: true}
+ ]}
+ ],
+ // For Enyo 2.2, we comment out these components to disable pinned mode which is still
+ // considered a work in progress.
+ /* pinnedReorderComponents: [
+ {name: "pinnedReorderItem", classes: "enyo-fit swipeGreen", components: [
+ {name: "pinnedReorderTitle", tag: "h2", allowHtml: true},
+ {name: "dropButton", kind: "onyx.Button", ontap: "dropPinnedRow", content: "Drop", classes: "dropButton"},
+ {name: "cancelButton", kind: "onyx.Button", ontap: "cancelPinnedMode", content: "Cancel", classes: "cancelButton"}
+ ]}
+ ], */
+ swipeableComponents: [
+ {name: "swipeItem", classes: "enyo-fit swipeGreen", components: [
+ {name: "swipeTitle", classes: "swipeTitle"}
+ ]}
+ ]
+ }
+ ],
+ rendered: function() {
+ this.inherited(arguments);
+ this.populateList();
+ },
+ listReorder: function(inSender, inEvent) {
+ var movedItem = enyo.clone(this.data[inEvent.reorderFrom]);
+ this.data.splice(inEvent.reorderFrom,1);
+ this.data.splice((inEvent.reorderTo),0,movedItem);
+ },
+ setupItem: function(inSender, inEvent) {
+ var i = inEvent.index;
+ if(!this.data[i]) {
+ return;
+ }
+ var currentLanguage = this.data[i].langs[this.data[i].currentIndex];
+ var val = this.data[i].val;
+ var number = this.languages[currentLanguage][val];
+ var serial = this.data[i].serial;
+ this.$.rowNumber.setContent("ROW " + i);
+ this.$.text.setContent(number);
+ this.$.serial.setContent("#" + serial);
+ },
+ setupReorderComponents: function(inSender, inEvent) {
+ var i = inEvent.index;
+ if(!this.data[i]) {
+ return;
+ }
+ var currentLanguage = this.data[i].langs[this.data[i].currentIndex];
+ var val = this.data[i].val;
+ var number = this.languages[currentLanguage][val];
+ this.$.reorderTitle.setContent(number);
+ },
+ /* setupPinnedReorderComponents: function(inSender, inEvent) {
+ var i = inEvent.index;
+ if(!this.data[i]) {
+ return;
+ }
+ var currentLanguage = this.data[i].langs[this.data[i].currentIndex];
+ var val = this.data[i].val;
+ var number = this.languages[currentLanguage][val];
+ this.$.pinnedReorderTitle.setContent(number);
+ }, */
+ //* Called when the "Drop" button is pressed on the pinned placeholder row
+ /* dropPinnedRow: function(inSender, inEvent) {
+ this.$.list.dropPinnedRow(inEvent);
+ }, */
+ //* Called when the "Cancel" button is pressed on the pinned placeholder row
+ /* cancelPinnedMode: function(inSender, inEvent) {
+ this.$.list.cancelPinnedMode(inEvent);
+ }, */
+ setupSwipeItem: function(inSender, inEvent) {
+ var i = inEvent.index;
+ if(!this.data[i]) {
+ return;
+ }
+ var newLang = (inEvent.xDirection == 1)
+ ? this.getNextLang(i)
+ : this.getPrevLang(i);
+ this.$.swipeTitle.setContent(this.data[i].langs[newLang]);
+ },
+ swipeComplete: function(inSender, inEvent) {
+ var i = inEvent.index;
+ this.data[i].currentIndex = (inEvent.xDirection == 1)
+ ? this.getNextLang(i)
+ : this.getPrevLang(i);
+ this.$.list.renderRow(i);
+ },
+ getNextLang: function(index) {
+ var currentLang = this.data[index].currentIndex;
+ return (currentLang + 1) % this.data[index].langs.length;
+ },
+ getPrevLang: function(index) {
+ var currentLang = this.data[index].currentIndex;
+ return (currentLang - 1 + this.data[index].langs.length) % this.data[index].langs.length;
+ },
+ populateList: function() {
+ this.createRandomData();
+ this.$.list.setCount(this.data.length);
+ this.$.list.reset();
+ },
+ createRandomData: function() {
+ var languages = this.getLanguages();
+ var langs;
+ var dataCount = parseInt(this.$.numRows.getValue(), 10);
+ this.data = [];
+ var sortFunc = function() {return 0.5 - Math.random();};
+ for(var i=0;i<dataCount;i++) {
+ langs = enyo.clone(languages);
+ langs.sort(sortFunc);
+ this.data.push({
+ langs: langs,
+ val: i % 10,
+ currentIndex: 0,
+ serial: i
+ });
+ }
+ this.data.sort(function() {return 0.5 - Math.random();});
+ },
+ getLanguages: function() {
+ return enyo.keys(this.languages);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListNoSelectSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListNoSelectSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListNoSelectSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListNoSelectSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Basic List Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <!-- reusing CSS from basic sample -->
+ <link href="ListBasicSample.css" rel="stylesheet">
+ <script src="NameGenerator.js" type="text/javascript"></script>
+ <script src="ListNoSelectSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.ListNoSelectSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListNoSelectSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListNoSelectSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListNoSelectSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListNoSelectSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.ListNoSelectSample",
+ classes: "list-sample enyo-fit",
+ components: [
+ {name: "list", kind: "List", count: 20000, noSelect: true, multiSelect: false, classes: "enyo-fit list-sample-list",
+ onSetupItem: "setupItem", components: [
+ {name: "item", classes: "list-sample-item enyo-border-box", components: [
+ {name: "index", classes: "list-sample-index"},
+ {name: "name"}
+ ]}
+ ]}
+ ],
+ names: [],
+ setupItem: function(inSender, inEvent) {
+ // this is the row we're setting up
+ var i = inEvent.index;
+ // make some mock data if we have none for this row
+ if (!this.names[i]) {
+ this.names[i] = makeName(5, 10, '', '');
+ }
+ var n = this.names[i];
+ var ni = ("00000000" + i).slice(-7);
+ this.$.name.setContent(n);
+ this.$.index.setContent(ni);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListOnyxItemSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListOnyxItemSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListOnyxItemSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListOnyxItemSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Onyx.Item List Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="ListBasicSample.css" rel="stylesheet"><!-- uses basic sample CSS -->
+ <script src="NameGenerator.js" type="text/javascript"></script>
+ <script src="ListOnyxItemSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.ListOnyxItemSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListOnyxItemSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListOnyxItemSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListOnyxItemSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListOnyxItemSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.ListOnyxItemSample",
+ classes: "list-sample enyo-fit",
+ components: [{
+ name: "list",
+ kind: "List",
+ count: 20000,
+ multiSelect: false,
+ classes: "enyo-fit list-sample-list",
+ onSetupItem: "setupItem",
+ components: [{
+ name: "item",
+ kind: "onyx.Item",
+ tapHighlight: true,
+ classes: "list-sample-item enyo-border-box",
+ components: [{
+ name: "index",
+ classes: "list-sample-index"
+ }, {
+ name: "name"
+ }]
+ }]
+ }],
+ names: [],
+ setupItem: function (inSender, inEvent) {
+ // this is the row we're setting up
+ var i = inEvent.index;
+ // make some mock data if we have none for this row
+ if (!this.names[i]) {
+ this.names[i] = makeName(5, 10, '', '');
+ }
+ var n = this.names[i];
+ var ni = ("00000000" + i).slice(-7);
+ // apply selection style if inSender (the list) indicates that this row is selected.
+ this.$.item.addRemoveClass("list-sample-selected", (i % 2 === 0));
+ this.$.name.setContent(n);
+ this.$.index.setContent(ni);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListPulldownSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListPulldownSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListPulldownSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListPulldownSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+a:link, a:visited {
+ color: lightblue;
+ text-decoration: underline;
+}
+.list-sample-pulldown-list {
+ background: grey;
+}
+.list-sample-pulldown-item {
+ border-bottom: 1px solid #0E0E0E;
+ padding: 12px 16px;
+ background-color: #333333;
+ /**/
+ font-size: 14px;
+ color: white;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListPulldownSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListPulldownSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListPulldownSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListPulldownSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Pulldown List Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="ListPulldownSample.css" rel="stylesheet">
+ <script src="ListPulldownSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.ListPulldownSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesListPulldownSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/ListPulldownSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/ListPulldownSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/ListPulldownSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,97 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.ListPulldownSample",
+ classes: "enyo-unselectable enyo-fit onyx",
+ kind: "FittableRows",
+ components: [
+ {kind: "onyx.Toolbar", components: [
+ {kind: "onyx.InputDecorator", components: [
+ {name: "searchInput", kind: "onyx.Input", value: "enyojs", placeholder: "Enter seach term"},
+ {kind: "Image", src: "assets/search-input-search.png", style: "width: 20px;"}
+ ]},
+ {kind: "onyx.Button", content: "search", ontap: "search"}
+ ]},
+ {name: "list", kind: "PulldownList", classes: "list-sample-pulldown-list", fit: true, onSetupItem: "setupItem", onPullRelease: "pullRelease", onPullComplete: "pullComplete", components: [
+ {style: "padding: 10px;", classes: "list-sample-pulldown-item enyo-border-box", components: [
+ {name: "icon", kind: "Image", style: "float: left; width: 48px; height: 48px; padding: 0 10px 10px 0;"},
+ {name: "name", tag: "span", style: "font-weight: bold;"},
+ {name: "handle", tag: "span", style: "color: lightgrey;"},
+ {name: "date", tag: "span", style: "float: right; color: lightgrey;"},
+ {tag: "br"},
+ {name: "text", tag: "p", style: "word-wrap: break-word;", allowHtml: true}
+ ]}
+ ]}
+ ],
+ rendered: function() {
+ this.inherited(arguments);
+ this.search();
+ },
+ pullRelease: function() {
+ this.pulled = true;
+ // add 1 second delay so we can see the loading message
+ setTimeout(enyo.bind(this, function() {
+ this.search();
+ }), 1000);
+ },
+ pullComplete: function() {
+ this.pulled = false;
+ this.$.list.reset();
+ },
+ search: function() {
+ // Capture searchText and strip any whitespace
+ var searchText = this.$.searchInput.getValue().replace(/^\s+|\s+$/g, '');
+
+ if (searchText !== "") {
+ var req = new enyo.JsonpRequest({
+ url: "http://search.twitter.com/search.json",
+ callbackName: "callback"
+ });
+ req.response(enyo.bind(this, "processSearchResults"));
+ req.go({q: searchText, rpp: 20});
+ } else {
+ // For whitespace searches, set new content value in order to display placeholder
+ this.$.searchInput.setValue(searchText);
+ }
+ },
+ processSearchResults: function(inRequest, inResponse) {
+ this.results = inResponse.results;
+ this.$.list.setCount(this.results.length);
+ if (this.pulled) {
+ this.$.list.completePull();
+ } else {
+ this.$.list.reset();
+ }
+ },
+ setupItem: function(inSender, inEvent) {
+ var i = inEvent.index;
+ var item = this.results[i];
+ this.$.icon.setSrc(item.profile_image_url);
+ this.$.name.setContent(item.from_user_name);
+ this.$.handle.setContent(" @" + item.from_user);
+ this.$.date.setContent(this.getRelativeDateString(item.created_at));
+ this.$.text.setContent(this.parseTweet(item.text));
+ },
+ getRelativeDateString: function(inDateString) {
+ var d = new Date(inDateString);
+ var td = new Date();
+ var s;
+ if (td.toLocaleDateString() == d.toLocaleDateString()) {
+ var dh = td.getHours() - d.getHours();
+ var dm = td.getMinutes() - d.getMinutes();
+ s = dh ? dh + " hour" : (dm ? dm + " minute" : td.getSeconds() - d.getSeconds() + " second");
+ } else {
+ var dmo = td.getMonth() - d.getMonth();
+ s = dmo ? dmo + " month" : td.getDate() - d.getDate() + " day";
+ }
+ return s.split(" ")[0] > 1 ? s + "s" : s;
+ },
+ parseTweet: function(inText) {
+ var t = inText;
+ t = t.replace(/[A-Za-z]+:\/\/[A-Za-z0-9_-]+\.[A-Za-z0-9_:%&~\?\/.=-]+/g, function(url) {
+ return "<a href='" + url + "'target='_blank'>" + url + "</a>";
+ });
+ return t.replace(/[@]+[A-Za-z0-9_-]+/, function(u) {
+ var username = u.replace("@", "");
+ return "<a href='http://twitter.com/" + u + "'target='_blank'>@" + username + "</a>";
+ });
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesNameGeneratorjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/NameGenerator.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/NameGenerator.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/NameGenerator.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+// Licensed under Creative Commons Attribution 3.0 License
+// attributed to: http://leapon.net/en/random-name-generator-javascript
+function rnd(minv, maxv) {
+ if (maxv < minv) return 0;
+ return Math.floor(Math.random()*(maxv-minv+1)) + minv;
+}
+
+function makeName(minlength, maxlength, prefix, suffix) {
+ prefix = prefix || '';
+ suffix = suffix || '';
+ // these weird character sets are intended to cope with the nature of English (e.g. char 'x' pops up less frequently than char 's')
+ // note: 'h' appears as consonants and vocals
+ var vocals = 'aeiouyh' + 'aeiou' + 'aeiou';
+ var cons = 'bcdfghjklmnpqrstvwxz' + 'bcdfgjklmnprstvw' + 'bcdfgjklmnprst';
+ var allchars = vocals + cons;
+ var length = rnd(minlength, maxlength) - prefix.length - suffix.length;
+ if (length < 1) length = 1;
+ var consnum = 0;
+ var i;
+ if (prefix.length > 0) {
+ for (i = 0; i < prefix.length; i++) {
+ if (consnum == 2) consnum = 0;
+ if (cons.indexOf(prefix[i]) != -1) {
+ consnum++;
+ }
+ }
+ }
+ else {
+ consnum = 1;
+ }
+ var name = prefix;
+ for (i = 0; i < length; i++)
+ {
+ //if we have used 2 consonants, the next char must be vocal.
+ if (consnum == 2)
+ {
+ touse = vocals;
+ consnum = 0;
+ }
+ else touse = allchars;
+ //pick a random character from the set we are goin to use.
+ c = touse.charAt(rnd(0, touse.length - 1));
+ name = name + c;
+ if (cons.indexOf(c) != -1) consnum++;
+ }
+ name = name.charAt(0).toUpperCase() + name.substring(1, name.length) + suffix;
+ return name;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesPersistentSwipeableItemSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/PersistentSwipeableItemSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/PersistentSwipeableItemSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/PersistentSwipeableItemSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+.list-sample-persistent-swipeable-item {
+ color: white;
+}
+.list-sample-persistent-swipeable-item-list {
+ background: url(assets/bg.png);
+}
+.list-sample-persistent-swipeable-item-item {
+ height: 80px;
+ border-top: 1px solid #000;
+ padding: 12px 16px;
+ background-color:rgba(0,0,0,0.5);
+}
+.list-sample-contacts-item > * {
+ display: inline-block;
+ vertical-align: middle;
+}
+.list-sample-persistent-swipeable-item-list .itemLabel {
+ float:left;
+ font-size:24px;
+ line-height:80px;
+ padding-left:20px;
+}
+.list-sample-persistent-swipeable-item-list .swipeGreen {
+ background-color:rgba(0,160,40,0.8);
+}
+.list-sample-persistent-swipeable-item-list .swipeRed {
+ background-color:rgba(160,0,40,0.8);
+}
+.list-sample-persistent-swipeable-item-list h2 {
+ margin:0px;
+ padding:0px 0px 0px 20px;
+ font-size:24px;
+ line-height:100px;
+}
+.list-sample-persistent-swipeable-item-list .swipeTitle {
+ font-size:30px;
+ font-weight:bold;
+ text-align:center;
+ line-height:100px;
+ padding:0px;
+ margin:0px;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesPersistentSwipeableItemSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/PersistentSwipeableItemSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/PersistentSwipeableItemSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/PersistentSwipeableItemSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Persistent Swipeable Item Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="PersistentSwipeableItemSample.css" rel="stylesheet">
+ <script src="PersistentSwipeableItemSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.PersistentSwipeableItemSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesPersistentSwipeableItemSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/PersistentSwipeableItemSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/PersistentSwipeableItemSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/PersistentSwipeableItemSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.PersistentSwipeableItemSample",
+ kind: "FittableRows",
+ classes: "list-sample-persistent-swipeable-item enyo-fit",
+ data: ["Cat","Dog","Hippopotamus"],
+ components: [
+ {kind: "List", classes: "list-sample-persistent-swipeable-item-list enyo-unselectable",
+ fit: true, multiSelect: true, reorderable: false, enableSwipe: true, centerReorderContainer: false,
+ onSetupItem: "setupItem",
+ onSetupSwipeItem: "setupSwipeItem",
+ onSwipeComplete: "swipeComplete",
+ components: [
+ {name: "item", classes: "list-sample-persistent-swipeable-item-item", components: [
+ {name: "text", classes: "itemLabel", allowHtml: true}
+ ]}
+ ],
+ swipeableComponents: [
+ {name: "swipeItem", classes: "enyo-fit swipeGreen", components: [
+ {name: "swipeTitle", classes: "swipeTitle", content: "This is a test"}
+ ]}
+ ]
+ }
+ ],
+ rendered: function() {
+ this.inherited(arguments);
+ this.populateList();
+ },
+ populateList: function() {
+ this.$.list.setCount(this.data.length);
+ this.$.list.reset();
+ },
+ setupItem: function(inSender, inEvent) {
+ if(!this.data[inEvent.index]) {
+ return;
+ }
+
+ this.$.text.setContent(this.data[inEvent.index]);
+ },
+ setupSwipeItem: function(inSender, inEvent) {
+ if(!this.data[inEvent.index]) {
+ return;
+ }
+
+ if(inEvent.xDirection === -1) {
+ // Persist swipeable item if swiped from right to left
+ this.$.list.setPersistSwipeableItem(true);
+ this.$.swipeTitle.setContent("This is a persistent item");
+ this.$.swipeItem.removeClass("swipeGreen");
+ this.$.swipeItem.addClass("swipeRed");
+ } else {
+ // Don't persist swipeable item if swiped from left to right
+ this.$.list.setPersistSwipeableItem(false);
+ this.$.swipeTitle.setContent("This is not a persistent item");
+ this.$.swipeItem.removeClass("swipeRed");
+ this.$.swipeItem.addClass("swipeGreen");
+ }
+ },
+ swipeComplete: function(inSender, inEvent) {
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsangelpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/angel.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/angel.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/angel.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/angel.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/angel.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsastrologerpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/astrologer.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/astrologer.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/astrologer.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/astrologer.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/astrologer.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsathletepng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/athlete.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/athlete.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/athlete.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/athlete.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/athlete.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsbabypng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/baby.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/baby.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/baby.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/baby.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/baby.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsclownpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/clown.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/clown.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/clown.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/clown.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/clown.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdevilpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/devil.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/devil.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/devil.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/devil.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/devil.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdoctorpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/doctor.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/doctor.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/doctor.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/doctor.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/doctor.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdudepng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdude2png"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude2.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude2.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude2.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude2.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude2.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdude3png"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude3.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude3.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude3.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude3.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude3.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdude4png"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude4.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude4.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude4.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude4.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude4.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdude5png"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude5.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude5.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude5.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude5.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude5.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsavatarsdude6png"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude6.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude6.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude6.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude6.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/avatars/dude6.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsbgpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/bg.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/bg.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/bg.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/bg.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/bg.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsitemhilitepng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/item-hilite.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/item-hilite.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/item-hilite.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/item-hilite.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/item-hilite.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetspulldownpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/pulldown.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/pulldown.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/pulldown.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/pulldown.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/pulldown.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetspulluppng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/pullup.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/pullup.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/pullup.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/pullup.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/pullup.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsremoveiconpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/remove-icon.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/remove-icon.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/remove-icon.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/remove-icon.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/remove-icon.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetssearchinputsearchpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/search-input-search.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/search-input-search.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/search-input-search.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/search-input-search.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/search-input-search.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplesassetsspinnergif"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/spinner.gif</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/spinner.gif
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/spinner.gif 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/spinner.gif 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/assets/spinner.gif
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/gif
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsamplespackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/samples/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/samples/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/samples/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+enyo.depends(
+ "NameGenerator.js",
+ "ListAroundSample.css",
+ "ListAroundSample.js",
+ "ListBasicSample.css",
+ "ListBasicSample.js",
+ "ListNoSelectSample.js",
+ "ListContactsSample.css",
+ "ListContactsSample.js",
+ "ListPulldownSample.css",
+ "ListPulldownSample.js",
+ "ListLanguagesSample.css",
+ "ListLanguagesSample.js",
+ "FlyweightRepeaterSample.css",
+ "FlyweightRepeaterSample.js",
+ "PersistentSwipeableItemSample.css",
+ "PersistentSwipeableItemSample.js"
+);
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/list/samples/package.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutlistsourceAlphaJumpListjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/source/AlphaJumpList.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/source/AlphaJumpList.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/source/AlphaJumpList.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+/**
+ A control that presents an alphabetic panel that you can select from, in
+ order to perform actions based on the item selected.
+
+ {kind: "AlphaJumpList", onSetupItem: "setupItem",
+ onAlphaJump: "alphaJump",
+ components: [
+ {name: "divider"},
+ {kind: "onyx.Item"}
+ ]
+ }
+
+*/
+enyo.kind({
+ name: "enyo.AlphaJumpList",
+ kind: "List",
+ //* @protected
+ scrollTools: [
+ {name: "jumper", kind: "AlphaJumper"}
+ ],
+ initComponents: function() {
+ this.createChrome(this.scrollTools);
+ this.inherited(arguments);
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ this.centerJumper();
+ },
+ resizeHandler: function() {
+ this.inherited(arguments);
+ this.centerJumper();
+ },
+ centerJumper: function() {
+ var b = this.getBounds(), sb = this.$.jumper.getBounds();
+ this.$.jumper.applyStyle("top", ((b.height - sb.height) / 2) + "px");
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsourceAlphaJumpercss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/source/AlphaJumper.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/source/AlphaJumper.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/source/AlphaJumper.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+.enyo-alpha-jumper {
+ text-transform: uppercase;
+ font-size: 11px;
+ xborder-radius: 12px;
+ position: absolute;
+ xbackground: white;
+ text-align: center;
+ right: 10px;
+ z-index: 1;
+ color: #333;
+ padding: 0 14px;
+}
+
+.enyo-alpha-jumper > *:first-child {
+ padding-top: 4px;
+ border-radius: 12px 12px 0 0;
+ border-top: 1px solid #333;
+}
+
+.enyo-alpha-jumper > *:last-child {
+ padding-bottom: 4px;
+ border-radius: 0 0 12px 12px;
+ border-bottom: 1px solid #333;
+}
+
+.enyo-alpha-jumper > * {
+ background: #eee;
+ padding: 1px 4px;
+ border-right: 1px solid #333;
+ border-left: 1px solid #333;
+}
+
+.enyo-alpha-jumper > .active {
+ background: #333;
+ color: white;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsourceAlphaJumperjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/source/AlphaJumper.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/source/AlphaJumper.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/source/AlphaJumper.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,70 @@
</span><ins>+enyo.kind({
+ name: "enyo.AlphaJumper",
+ classes: "enyo-alpha-jumper enyo-border-box",
+ published: {
+ marker: null
+ },
+ events: {
+ onAlphaJump: ""
+ },
+ handlers: {
+ ondown: "down",
+ onmove: "move",
+ onup: "up"
+ },
+ initComponents: function() {
+ for (var s="A".charCodeAt(0), i=s; i<s+26; i++) {
+ this.createComponent({content: String.fromCharCode(i)});
+ }
+ this.inherited(arguments);
+ },
+ down: function(inSender, inEvent) {
+ if (this.tracking) {
+ enyo.dispatcher.release();
+ }
+ this.tracking = true;
+ if (this.hasNode()) {
+ var b = this.node.getBoundingClientRect();
+ // IE8 does not return width
+ var w = (b.width === undefined) ? (b.right - b.left) : b.width;
+ this.x = b.left + w/2;
+ }
+ enyo.dispatcher.capture(this);
+ this.track(inEvent);
+ },
+ move: function(inSender, inEvent) {
+ if (this.tracking) {
+ this.track(inEvent);
+ }
+ },
+ up: function() {
+ if (this.tracking) {
+ enyo.dispatcher.release();
+ this.setMarker(null);
+ this.tracking = false;
+ }
+ },
+ track: function(inEvent) {
+ var n = document.elementFromPoint(this.x, inEvent.pageY);
+ var c = this.nodeToControl(n);
+ if (c) {
+ this.setMarker(c);
+ }
+ },
+ nodeToControl: function(inNode) {
+ for (var i=0, c$=this.controls, c; (c=c$[i]); i++) {
+ if (inNode == c.hasNode()) {
+ return c;
+ }
+ }
+ },
+ markerChanged: function(inLast) {
+ if (inLast) {
+ inLast.removeClass("active");
+ }
+ if (this.marker) {
+ this.marker.addClass("active");
+ this.doAlphaJump({letter: this.marker.getContent(), index: this.marker.indexInContainer()});
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsourceAroundListjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/source/AroundList.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/source/AroundList.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/source/AroundList.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,67 @@
</span><ins>+/**
+ _enyo.AroundList_ is an <a href="#enyo.List">enyo.List</a> that allows
+ content to be displayed around its rows.
+
+ {kind: "enyo.AroundList", onSetupItem: "setupItem",
+ aboveComponents: [
+ {content: "Content above the list"}
+ ],
+ components: [
+ {content: "List item"}
+ ]
+ }
+*/
+enyo.kind({
+ name: "enyo.AroundList",
+ kind: "enyo.List",
+ //* @protected
+ listTools: [
+ {name: "port", classes: "enyo-list-port enyo-border-box", components: [
+ {name: "aboveClient"},
+ {name: "generator", kind: "FlyweightRepeater", canGenerate: false, components: [
+ {tag: null, name: "client"}
+ ]},
+ {name: "holdingarea", allowHtml: true, classes: "enyo-list-holdingarea"},
+ {name: "page0", allowHtml: true, classes: "enyo-list-page"},
+ {name: "page1", allowHtml: true, classes: "enyo-list-page"},
+ {name: "belowClient"},
+ {name: "placeholder"},
+ {name: "swipeableComponents", style: "position:absolute; display:block; top:-1000px; left:0px;"}
+ ]}
+ ],
+ //* @public
+ //* Block of components to be rendered above the list
+ aboveComponents: null,
+ //* @protected
+ initComponents: function() {
+ this.inherited(arguments);
+ if (this.aboveComponents) {
+ this.$.aboveClient.createComponents(this.aboveComponents, {owner: this.owner});
+ }
+ if (this.belowComponents) {
+ this.$.belowClient.createComponents(this.belowComponents, {owner: this.owner});
+ }
+ },
+ updateMetrics: function() {
+ this.defaultPageHeight = this.rowsPerPage * (this.rowHeight || 100);
+ this.pageCount = Math.ceil(this.count / this.rowsPerPage);
+ this.aboveHeight = this.$.aboveClient.getBounds().height;
+ this.belowHeight = this.$.belowClient.getBounds().height;
+ this.portSize = this.aboveHeight + this.belowHeight;
+ for (var i=0; i < this.pageCount; i++) {
+ this.portSize += this.getPageHeight(i);
+ }
+ this.adjustPortSize();
+ },
+ positionPage: function(inPage, inTarget) {
+ inTarget.pageNo = inPage;
+ var y = this.pageToPosition(inPage);
+ var o = this.bottomUp ? this.belowHeight : this.aboveHeight;
+ y += o;
+ inTarget.applyStyle(this.pageBound, y + "px");
+ },
+ scrollToContentStart: function() {
+ var y = this.bottomUp ? this.belowHeight : this.aboveHeight;
+ this.setScrollPosition(y);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsourceFlyweightRepeaterjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/source/FlyweightRepeater.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/source/FlyweightRepeater.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/source/FlyweightRepeater.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,248 @@
</span><ins>+/**
+ _enyo.FlyweightRepeater_ is a control that displays a repeating list of
+ rows, suitable for displaying medium-sized lists (up to ~100 items). A
+ flyweight strategy is employed to render one set of row controls, as needed,
+ for as many rows as are contained in the repeater.
+
+ The FlyweightRepeater's _components_ block contains the controls to be used
+ for a single row. This set of controls will be rendered for each row. You
+ may customize row rendering by handling the _onSetupItem_ event.
+
+ The controls inside a FlyweightRepeater are non-interactive. This means that
+ calling methods that would normally cause rendering to occur (e.g.,
+ _setContent_) will not do so. However, you can force a row to render by
+ calling _renderRow(inRow)_.
+
+ In addition, you can force a row to be temporarily interactive by calling
+ _prepareRow(inRow)_. Call the _lockRow_ method when the interaction is
+ complete.
+
+ For more information, see the documentation on
+ [Lists](https://github.com/enyojs/enyo/wiki/Lists)
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.FlyweightRepeater",
+ published: {
+ //* Number of rows to render
+ count: 0,
+ /**
+ If true, the selection mechanism is disabled. Tap events are still
+ sent, but items won't be automatically re-rendered when tapped.
+ */
+ noSelect: false,
+ //* If true, multiple selections are allowed
+ multiSelect: false,
+ //* If true, the selected item will toggle
+ toggleSelected: false,
+ /**
+ Used to specify CSS classes for the repeater's wrapper component
+ (client). Input is identical to enyo.Control.setClasses()
+ */
+ clientClasses: '',
+ /**
+ Used to specify custom styling for the repeater's wrapper component
+ (client). Input is identical to enyo.Control.setStyle()
+ */
+ clientStyle: '',
+ /**
+ Offset applied to row number during generation. Used to allow a
+ items to use a natural index instead of being forced to be
+ 0-based. Must be positive, as row -1 is used for undefined rows
+ in the event system.
+ */
+ rowOffset: 0
+ },
+ events: {
+ /**
+ Fires once per row at render time.
+
+ _inEvent.index_ contains the current row index.
+
+ _inEvent.selected_ is a boolean indicating whether the current row
+ is selected.
+ */
+ onSetupItem: "",
+ //* Fires after an individual row has been rendered from a call to _renderRow()_.
+ onRenderRow: ""
+ },
+ //* design-time attribute, indicates if row indices run
+ //* from [0.._count_-1] (false) or [_count_-1..0] (true)
+ bottomUp: false,
+ //* @protected
+ components: [
+ {kind: "Selection", onSelect: "selectDeselect", onDeselect: "selectDeselect"},
+ {name: "client"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.noSelectChanged();
+ this.multiSelectChanged();
+ this.clientClassesChanged();
+ this.clientStyleChanged();
+ },
+ noSelectChanged: function() {
+ if (this.noSelect) {
+ this.$.selection.clear();
+ }
+ },
+ multiSelectChanged: function() {
+ this.$.selection.setMulti(this.multiSelect);
+ },
+ clientClassesChanged: function() {
+ this.$.client.setClasses(this.clientClasses);
+ },
+ clientStyleChanged: function() {
+ this.$.client.setStyle(this.clientStyle);
+ },
+ setupItem: function(inIndex) {
+ this.doSetupItem({index: inIndex, selected: this.isSelected(inIndex)});
+ },
+ //* Renders the list.
+ generateChildHtml: function() {
+ var h = "";
+ this.index = null;
+ // note: can supply a rowOffset
+ // and indicate if rows should be rendered top down or bottomUp
+ for (var i=0, r=0; i<this.count; i++) {
+ r = this.rowOffset + (this.bottomUp ? this.count - i-1 : i);
+ this.setupItem(r);
+ this.$.client.setAttribute("data-enyo-index", r);
+ h += this.inherited(arguments);
+ this.$.client.teardownRender();
+ }
+ return h;
+ },
+ previewDomEvent: function(inEvent) {
+ var i = this.index = this.rowForEvent(inEvent);
+ inEvent.rowIndex = inEvent.index = i;
+ inEvent.flyweight = this;
+ },
+ decorateEvent: function(inEventName, inEvent, inSender) {
+ // decorate event with index found via dom iff event does not already contain an index.
+ var i = (inEvent && inEvent.index != null) ? inEvent.index : this.index;
+ if (inEvent && i != null) {
+ inEvent.index = i;
+ inEvent.flyweight = this;
+ }
+ this.inherited(arguments);
+ },
+ tap: function(inSender, inEvent) {
+ // ignore taps if selecting is disabled or if they don't target a row
+ if (this.noSelect || inEvent.index === -1) {
+ return;
+ }
+ if (this.toggleSelected) {
+ this.$.selection.toggle(inEvent.index);
+ } else {
+ this.$.selection.select(inEvent.index);
+ }
+ },
+ selectDeselect: function(inSender, inEvent) {
+ this.renderRow(inEvent.key);
+ },
+ //* @public
+ //* Returns the repeater's _selection_ component.
+ getSelection: function() {
+ return this.$.selection;
+ },
+ //* Gets the selection state for the given row index.
+ isSelected: function(inIndex) {
+ return this.getSelection().isSelected(inIndex);
+ },
+ //* Renders the row specified by _inIndex_.
+ renderRow: function(inIndex) {
+ // do nothing if index is out-of-range
+ if (inIndex < this.rowOffset || inIndex >= this.count + this.rowOffset) {
+ return;
+ }
+ //this.index = null;
+ // always call the setupItem callback, as we may rely on the post-render state
+ this.setupItem(inIndex);
+ var node = this.fetchRowNode(inIndex);
+ if (node) {
+ enyo.dom.setInnerHtml(node, this.$.client.generateChildHtml());
+ this.$.client.teardownChildren();
+ this.doRenderRow({rowIndex: inIndex});
+ }
+ },
+ //* Fetches the DOM node for the given row index.
+ fetchRowNode: function(inIndex) {
+ if (this.hasNode()) {
+ return this.node.querySelector('[data-enyo-index="' + inIndex + '"]');
+ }
+ },
+ //* Fetches the row number corresponding with the target of a given event.
+ rowForEvent: function(inEvent) {
+ if (!this.hasNode()) {
+ return -1;
+ }
+ var n = inEvent.target;
+ while (n && n !== this.node) {
+ var i = n.getAttribute && n.getAttribute("data-enyo-index");
+ if (i !== null) {
+ return Number(i);
+ }
+ n = n.parentNode;
+ }
+ return -1;
+ },
+ //* Prepares the row specified by _inIndex_ such that changes made to the
+ //* controls inside the repeater will be rendered for the given row.
+ prepareRow: function(inIndex) {
+ // do nothing if index is out-of-range
+ if (inIndex < 0 || inIndex >= this.count) {
+ return;
+ }
+ // update row internals to match model
+ this.setupItem(inIndex);
+ var n = this.fetchRowNode(inIndex);
+ enyo.FlyweightRepeater.claimNode(this.$.client, n);
+ },
+ //* Prevents rendering of changes made to controls inside the repeater.
+ lockRow: function() {
+ this.$.client.teardownChildren();
+ },
+ //* Prepares the row specified by _inIndex_ such that changes made to the
+ //* controls in the row will be rendered in the given row; then performs the
+ //* function _inFunc_, and, finally, locks the row.
+ performOnRow: function(inIndex, inFunc, inContext) {
+ // do nothing if index is out-of-range
+ if (inIndex < 0 || inIndex >= this.count) {
+ return;
+ }
+ if (inFunc) {
+ this.prepareRow(inIndex);
+ enyo.call(inContext || null, inFunc);
+ this.lockRow();
+ }
+ },
+ statics: {
+ //* Associates a flyweight rendered control (_inControl_) with a
+ //* rendering context specified by _inNode_.
+ claimNode: function(inControl, inNode) {
+ var n;
+ if (inNode) {
+ if (inNode.id !== inControl.id) {
+ n = inNode.querySelector("#" + inControl.id);
+ }
+ else {
+ // inNode is already the right node, so just use it
+ n = inNode;
+ }
+ }
+ // FIXME: consider controls generated if we found a node or tag: null, the later so can teardown render
+ inControl.generated = Boolean(n || !inControl.tag);
+ inControl.node = n;
+ if (inControl.node) {
+ inControl.rendered();
+ } else {
+ //enyo.log("Failed to find node for", inControl.id, inControl.generated);
+ }
+ // update control's class cache based on the node contents
+ for (var i=0, c$=inControl.children, c; (c=c$[i]); i++) {
+ this.claimNode(c, inNode);
+ }
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsourceListcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/source/List.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/source/List.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/source/List.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+.enyo-list {
+ position: relative;
+}
+
+.enyo-list-port {
+ overflow: hidden;
+ position: relative;
+ height: 1000000px;
+}
+
+.enyo-list-page, .enyo-list-holdingarea {
+ position: absolute;
+ left: 0;
+ right: 0;
+}
+
+.enyo-list-holdingarea {
+ top: -10000px;
+}
+
+.enyo-pinned-list-placeholder {
+ border: 1px solid red;
+ position: absolute;
+ top: 0; left: 0;
+ z-index: 1000;
+ background: transparent;
+ overflow: hidden;
+}
+
+.enyo-pinned-list-placeholder button {
+ width: 100px; height: 100%;
+ position: absolute;
+ top: 0; right: 0;
+}
+
+.enyo-list-reorder-container {
+ position: absolute;
+ top: 0; left: 0;
+ z-index: 1000;
+ background: transparent;
+ overflow: hidden;
+}
+
+.enyo-animatedTopAndLeft {
+ -webkit-transition: top 0.1s linear, left 0.1s linear;
+ -moz-transition: top 0.1s linear, left 0.1s linear;
+ -o-transition: top 0.1s linear, left 0.1s linear;
+ transition: top 0.1s linear, left 0.1s linear;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsourceListjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/source/List.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/source/List.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/source/List.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,1502 @@
</span><ins>+/**
+ _enyo.List_ is a control that displays a scrolling list of rows, suitable
+ for displaying very large lists. It is optimized such that only a small
+ portion of the list is rendered at a given time. A flyweight pattern is
+ employed, in which controls placed inside the list are created once, but
+ rendered for each list item. For this reason, it's best to use only simple
+ controls in a List, such as <a href="#enyo.Control">enyo.Control</a> and
+ <a href="#enyo.Image">enyo.Image</a>.
+
+ A List's _components_ block contains the controls to be used for a single
+ row. This set of controls will be rendered for each row. You may customize
+ row rendering by handling the _onSetupItem_ event.
+
+ Events fired from within list rows contain the _index_ property, which may
+ be used to identify the row from which the event originated.
+
+ Beginning with Enyo 2.2, lists have built-in support for swipeable and
+ reorderable list items. Individual list items are swipeable by default; to
+ enable reorderability, set the _reorderable_ property to true.
+
+ For more information, see the documentation on
+ [Lists](https://github.com/enyojs/enyo/wiki/Lists)
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.List",
+ kind: "Scroller",
+ classes: "enyo-list",
+ published: {
+ /**
+ The number of rows contained in the list. Note that as the amount of
+ list data changes, _setRows_ can be called to adjust the number of
+ rows. To re-render the list at the current position when the count
+ has changed, call the _refresh_ method. If the whole data model of
+ the list has changed and you want to redisplay from the top, call
+ the _reset_ method instead.
+ */
+ count: 0,
+ /**
+ The number of rows to be shown on a given list page segment.
+ There is generally no need to adjust this value.
+ */
+ rowsPerPage: 50,
+ /**
+ If true, renders the list such that row 0 is at the bottom of the
+ viewport and the beginning position of the list is scrolled to the
+ bottom
+ */
+ bottomUp: false,
+ /**
+ If true, the selection mechanism is disabled. Tap events are still
+ sent, but items won't be automatically re-rendered when tapped.
+ */
+ noSelect: false,
+ //* If true, multiple selections are allowed
+ multiSelect: false,
+ //* If true, the selected item will toggle
+ toggleSelected: false,
+ //* If true, the list will assume all rows have the same height for optimization
+ fixedHeight: false,
+ //* If true, the list will allow the user to reorder list items
+ reorderable: false,
+ //* If true and _reorderable_ is true, reorderable item will be centered on finger
+ //* when created. When false, it will be created over old item and will then track finger.
+ centerReorderContainer: true,
+ //* Array containing components shown as the placeholder when reordering list items.
+ reorderComponents: [],
+ //* Array containing components for the pinned version of a row. If not provided, reordering
+ //* will not support pinned mode.
+ pinnedReorderComponents: [],
+ //* Array containing any swipeable components that will be used
+ swipeableComponents: [],
+ //* If true, swipe functionality is enabled
+ enableSwipe: false,
+ //* If true, tells list to persist the current swipeable item
+ persistSwipeableItem: false
+ },
+ events: {
+ /**
+ Fires once per row at render time.
+ _inEvent.index_ contains the current row index.
+ */
+ onSetupItem: "",
+ //* Reorder events
+ onSetupReorderComponents: "",
+ onSetupPinnedReorderComponents: "",
+ onReorder: "",
+ //* Swipe events
+ onSetupSwipeItem: "",
+ onSwipeDrag: "",
+ onSwipe: "",
+ onSwipeComplete: ""
+ },
+ handlers: {
+ onAnimateFinish: "animateFinish",
+ onRenderRow: "rowRendered",
+ ondragstart: "dragstart",
+ ondrag: "drag",
+ ondragfinish: "dragfinish",
+ onup: "up",
+ onholdpulse: "holdpulse"
+ },
+ //* @protected
+ rowHeight: 0,
+ listTools: [
+ {name: "port", classes: "enyo-list-port enyo-border-box", components: [
+ {name: "generator", kind: "FlyweightRepeater", canGenerate: false, components: [
+ {tag: null, name: "client"}
+ ]},
+ {name: "holdingarea", allowHtml: true, classes: "enyo-list-holdingarea"},
+ {name: "page0", allowHtml: true, classes: "enyo-list-page"},
+ {name: "page1", allowHtml: true, classes: "enyo-list-page"},
+ {name: "placeholder"},
+ {name: "swipeableComponents", style: "position:absolute; display:block; top:-1000px; left:0;"}
+ ]}
+ ],
+
+ //* Reorder vars
+ // how long, in ms, to wait for to active reordering
+ reorderHoldTimeMS: 600,
+ // index of the row that we're moving
+ draggingRowIndex: -1,
+ // node of the dragged row, used to keep touch events alive
+ draggingRowNode: null,
+ // index of the row before which we'll show the placeholder item. If the placeholder
+ // is at the end of the list, this will be one larger than the row count.
+ placeholderRowIndex: -1,
+ // determines scroll height at top/bottom of list where dragging will cause scroll
+ dragToScrollThreshold: 0.1,
+ // used to determine direction of scrolling during reordering
+ prevScrollTop: 0,
+ // how many MS between scroll events when autoscrolling
+ autoScrollTimeoutMS: 20,
+ // holds timeout ID for autoscroll
+ autoScrollTimeout: null,
+ // keep last event Y coordinate to update placeholder position during autoscroll
+ autoscrollPageY: 0,
+ // set to true to indicate that we're in pinned reordering mode
+ pinnedReorderMode: false,
+ // y-coordinate of the original location of the pinned row
+ initialPinPosition: -1,
+ // set to true after drag-and-drop has moved the reordering item at least one space
+ // used to activate pin mode if item is dropped immediately
+ itemMoved: false,
+ // this tracks the page where the being-dragged item is so we can detect
+ // when we switch pages and need to adjust rendering
+ currentPageNumber: -1,
+ // timeout for completing reorder operation
+ completeReorderTimeout: null,
+
+ //* Swipeable vars
+ // Index of swiped item
+ swipeIndex: null,
+ // Direction of swipe
+ swipeDirection: null,
+ // True if a persistent item is currently persisting
+ persistentItemVisible: false,
+ // Side from which the persisting item came
+ persistentItemOrigin: null,
+ // True if swipe was completed
+ swipeComplete: false,
+ // Timeout used to wait before completing swipe action
+ completeSwipeTimeout: null,
+ // Time in MS to wait before completing swipe action
+ completeSwipeDelayMS: 500,
+ // Time in MS for normal swipe animation
+ normalSwipeSpeedMS: 200,
+ // Time in seconds for fast swipe animation
+ fastSwipeSpeedMS: 100,
+ // Percentage of a swipe needed to force completion of the swipe
+ percentageDraggedThreshold: 0.2,
+
+ importProps: function(inProps) {
+ // force touch on desktop when we have reorderable items to work around
+ // problems with native scroller
+ if (inProps && inProps.reorderable) {
+ this.touch = true;
+ }
+ this.inherited(arguments);
+ },
+ create: function() {
+ this.pageHeights = [];
+ this.inherited(arguments);
+ this.getStrategy().translateOptimized = true;
+ this.bottomUpChanged();
+ this.noSelectChanged();
+ this.multiSelectChanged();
+ this.toggleSelectedChanged();
+ // setup generator to default to "full-list" values
+ this.$.generator.setRowOffset(0);
+ this.$.generator.setCount(this.count);
+ },
+ initComponents: function() {
+ this.createReorderTools();
+ this.inherited(arguments);
+ this.createSwipeableComponents();
+ },
+ createReorderTools: function() {
+ this.createComponent({
+ name: "reorderContainer", classes: "enyo-list-reorder-container",
+ ondown: "sendToStrategy", ondrag: "sendToStrategy",
+ ondragstart: "sendToStrategy", ondragfinish: "sendToStrategy",
+ onflick: "sendToStrategy"});
+ },
+ createStrategy: function() {
+ this.controlParentName = "strategy";
+ this.inherited(arguments);
+ this.createChrome(this.listTools);
+ this.controlParentName = "client";
+ this.discoverControlParent();
+ },
+ createSwipeableComponents: function() {
+ for(var i=0;i<this.swipeableComponents.length;i++) {
+ this.$.swipeableComponents.createComponent(this.swipeableComponents[i], {owner: this.owner});
+ }
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ this.$.generator.node = this.$.port.hasNode();
+ this.$.generator.generated = true;
+ this.reset();
+ },
+ resizeHandler: function() {
+ this.inherited(arguments);
+ this.refresh();
+ },
+ bottomUpChanged: function() {
+ this.$.generator.bottomUp = this.bottomUp;
+ this.$.page0.applyStyle(this.pageBound, null);
+ this.$.page1.applyStyle(this.pageBound, null);
+ this.pageBound = this.bottomUp ? "bottom" : "top";
+ if (this.hasNode()) {
+ this.reset();
+ }
+ },
+ noSelectChanged: function() {
+ this.$.generator.setNoSelect(this.noSelect);
+ },
+ multiSelectChanged: function() {
+ this.$.generator.setMultiSelect(this.multiSelect);
+ },
+ toggleSelectedChanged: function() {
+ this.$.generator.setToggleSelected(this.toggleSelected);
+ },
+ countChanged: function() {
+ if (this.hasNode()) {
+ this.updateMetrics();
+ }
+ },
+ sendToStrategy: function(s,e) {
+ this.$.strategy.dispatchEvent("on" + e.type, e, s);
+ },
+ updateMetrics: function() {
+ this.defaultPageHeight = this.rowsPerPage * (this.rowHeight || 100);
+ this.pageCount = Math.ceil(this.count / this.rowsPerPage);
+ this.portSize = 0;
+ for (var i=0; i < this.pageCount; i++) {
+ this.portSize += this.getPageHeight(i);
+ }
+ this.adjustPortSize();
+ },
+ //* Hold pulse handler - use this to delay before running hold logic
+ holdpulse: function(inSender,inEvent) {
+ // don't activate if we're not supporting reordering or if we've already
+ // activated the reorder logic
+ if(!this.getReorderable() || this.isReordering()) {
+ return;
+ }
+ // first pulse event that exceeds our minimum hold time activates
+ if (inEvent.holdTime >= this.reorderHoldTimeMS) {
+ // determine if we should handle the hold event
+ if(this.shouldStartReordering(inSender, inEvent)) {
+ inEvent.preventDefault();
+ this.startReordering(inEvent);
+ return false;
+ }
+ }
+ },
+ //* DragStart event handler
+ dragstart: function(inSender, inEvent) {
+ // stop dragstart from propogating if we're in reorder mode
+ if (this.isReordering()) {
+ return true;
+ }
+ if (this.isSwipeable()) {
+ return this.swipeDragStart(inSender, inEvent);
+ }
+ },
+ //* Drag event handler
+ drag: function(inSender, inEvent) {
+ // determine if we should handle the drag event
+ if(this.shouldDoReorderDrag(inEvent)) {
+ inEvent.preventDefault();
+ this.reorderDrag(inEvent);
+ return true;
+ }
+ else if (this.isSwipeable()) {
+ inEvent.preventDefault();
+ this.swipeDrag(inSender, inEvent);
+ return true;
+ }
+ },
+ //* Dragfinish event handler
+ dragfinish: function(inSender, inEvent) {
+ if(this.isReordering()) {
+ this.finishReordering(inSender, inEvent);
+ }
+ else if (this.isSwipeable()) {
+ this.swipeDragFinish(inSender, inEvent);
+ }
+ },
+ //* up event handler
+ up: function(inSender, inEvent) {
+ if(this.isReordering()) {
+ this.finishReordering(inSender, inEvent);
+ }
+ },
+ generatePage: function(inPageNo, inTarget) {
+ this.page = inPageNo;
+ var r = this.rowsPerPage * this.page;
+ this.$.generator.setRowOffset(r);
+ var rpp = Math.min(this.count - r, this.rowsPerPage);
+ this.$.generator.setCount(rpp);
+ var html = this.$.generator.generateChildHtml();
+ inTarget.setContent(html);
+ // prevent reordering row from being draw twice
+ if(this.getReorderable() && this.draggingRowIndex > -1) {
+ this.hideReorderingRow();
+ }
+ var pageHeight = inTarget.getBounds().height;
+ // if rowHeight is not set, use the height from the first generated page
+ if (!this.rowHeight && pageHeight > 0) {
+ this.rowHeight = Math.floor(pageHeight / rpp);
+ this.updateMetrics();
+ }
+ // update known page heights
+ if (!this.fixedHeight) {
+ var h0 = this.getPageHeight(inPageNo);
+ this.pageHeights[inPageNo] = pageHeight;
+ this.portSize += pageHeight - h0;
+ }
+ },
+ //* map a row index number to the page number it would be in
+ pageForRow: function(inIndex) {
+ return Math.floor(inIndex / this.rowsPerPage);
+ },
+ // preserve original DOM node because it may be needed to route touch events
+ preserveDraggingRowNode: function(pageNo) {
+ if (this.draggingRowNode && this.pageForRow(this.draggingRowIndex) === pageNo) {
+ this.$.holdingarea.hasNode().appendChild(this.draggingRowNode);
+ this.draggingRowNode = null;
+ this.removedInitialPage = true;
+ }
+ },
+ update: function(inScrollTop) {
+ var updated = false;
+ // get page info for position
+ var pi = this.positionToPageInfo(inScrollTop);
+ // zone line position
+ var pos = pi.pos + this.scrollerHeight/2;
+ // leap-frog zone position
+ var k = Math.floor(pos/Math.max(pi.height, this.scrollerHeight) + 1/2) + pi.no;
+ // which page number for page0 (even number pages)?
+ var p = (k % 2 === 0) ? k : k-1;
+ if (this.p0 != p && this.isPageInRange(p)) {
+ this.preserveDraggingRowNode(this.p0);
+ this.generatePage(p, this.$.page0);
+ this.positionPage(p, this.$.page0);
+ this.p0 = p;
+ updated = true;
+ this.p0RowBounds = this.getPageRowHeights(this.$.page0);
+ }
+ // which page number for page1 (odd number pages)?
+ p = (k % 2 === 0) ? Math.max(1, k-1) : k;
+ // position data page 1
+ if (this.p1 != p && this.isPageInRange(p)) {
+ this.preserveDraggingRowNode(this.p1);
+ this.generatePage(p, this.$.page1);
+ this.positionPage(p, this.$.page1);
+ this.p1 = p;
+ updated = true;
+ this.p1RowBounds = this.getPageRowHeights(this.$.page1);
+ }
+ if (updated) {
+ // reset generator back to "full-list" values
+ this.$.generator.setRowOffset(0);
+ this.$.generator.setCount(this.count);
+ if (!this.fixedHeight) {
+ this.adjustBottomPage();
+ this.adjustPortSize();
+ }
+ }
+ },
+ getPageRowHeights: function(page) {
+ var rows = {};
+ var allDivs = page.hasNode().querySelectorAll("div[data-enyo-index]");
+ for (var i=0, index, bounds; i < allDivs.length; i++) {
+ index = allDivs[i].getAttribute("data-enyo-index");
+ if (index !== null) {
+ bounds = enyo.dom.getBounds(allDivs[i]);
+ rows[parseInt(index, 10)] = {height: bounds.height, width: bounds.width};
+ }
+ }
+ return rows;
+ },
+ updateRowBounds: function(index) {
+ if (this.p0RowBounds[index]) {
+ this.updateRowBoundsAtIndex(index, this.p0RowBounds, this.$.page0);
+ }
+ else if (this.p1RowBounds[index]) {
+ this.updateRowBoundsAtIndex(index, this.p1RowBounds, this.$.page1);
+ }
+ },
+ updateRowBoundsAtIndex: function(index, rows, page) {
+ var rowDiv = page.hasNode().querySelector('div[data-enyo-index="' + index + '"]');
+ var bounds = enyo.dom.getBounds(rowDiv);
+ rows[index].height = bounds.height;
+ rows[index].width = bounds.width;
+ },
+ updateForPosition: function(inPos) {
+ this.update(this.calcPos(inPos));
+ },
+ calcPos: function(inPos) {
+ return (this.bottomUp ? (this.portSize - this.scrollerHeight - inPos) : inPos);
+ },
+ adjustBottomPage: function() {
+ var bp = this.p0 >= this.p1 ? this.$.page0 : this.$.page1;
+ this.positionPage(bp.pageNo, bp);
+ },
+ adjustPortSize: function() {
+ this.scrollerHeight = this.getBounds().height;
+ var s = Math.max(this.scrollerHeight, this.portSize);
+ this.$.port.applyStyle("height", s + "px");
+ },
+ positionPage: function(inPage, inTarget) {
+ inTarget.pageNo = inPage;
+ var y = this.pageToPosition(inPage);
+ inTarget.applyStyle(this.pageBound, y + "px");
+ },
+ pageToPosition: function(inPage) {
+ var y = 0;
+ var p = inPage;
+ while (p > 0) {
+ p--;
+ y += this.getPageHeight(p);
+ }
+ return y;
+ },
+ positionToPageInfo: function(inY) {
+ var page = -1;
+ var p = this.calcPos(inY);
+ var h = this.defaultPageHeight;
+ while (p >= 0) {
+ page++;
+ h = this.getPageHeight(page);
+ p -= h;
+ }
+ page = Math.max(page, 0);
+ return {
+ no: page,
+ height: h,
+ pos: p + h,
+ startRow: (page * this.rowsPerPage),
+ endRow: Math.min((page + 1) * this.rowsPerPage - 1, this.count - 1)
+ };
+ },
+ isPageInRange: function(inPage) {
+ return inPage == Math.max(0, Math.min(this.pageCount-1, inPage));
+ },
+ getPageHeight: function(inPageNo) {
+ var height = this.pageHeights[inPageNo];
+ // estimate the height based on how many rows are in this page
+ if (!height) {
+ var firstRow = this.rowsPerPage * inPageNo;
+ var numRows = Math.min(this.count - firstRow, this.rowsPerPage);
+ height = this.defaultPageHeight * (numRows / this.rowsPerPage);
+ }
+ // can never return height of 0, as that would lead to infinite loops
+ return Math.max(1, height);
+ },
+ invalidatePages: function() {
+ this.p0 = this.p1 = null;
+ this.p0RowBounds = {};
+ this.p1RowBounds = {};
+ // clear the html in our render targets
+ this.$.page0.setContent("");
+ this.$.page1.setContent("");
+ },
+ invalidateMetrics: function() {
+ this.pageHeights = [];
+ this.rowHeight = 0;
+ this.updateMetrics();
+ },
+ scroll: function(inSender, inEvent) {
+ var r = this.inherited(arguments);
+ var pos = this.getScrollTop();
+ if (this.lastPos === pos) {
+ return r;
+ }
+ this.lastPos = pos;
+ this.update(pos);
+ if (this.pinnedReorderMode) {
+ this.reorderScroll(inSender, inEvent);
+ }
+ return r;
+ },
+ setScrollTop: function(inScrollTop) {
+ this.update(inScrollTop);
+ this.inherited(arguments);
+ this.twiddle();
+ },
+ getScrollPosition: function() {
+ return this.calcPos(this.getScrollTop());
+ },
+ setScrollPosition: function(inPos) {
+ this.setScrollTop(this.calcPos(inPos));
+ },
+ //* @public
+ //* Scrolls the list so the last item is visible.
+ scrollToBottom: function() {
+ this.update(this.getScrollBounds().maxTop);
+ this.inherited(arguments);
+ },
+ //* Scrolls to the specified row.
+ scrollToRow: function(inRow) {
+ var page = this.pageForRow(inRow);
+ var pageRow = inRow % this.rowsPerPage;
+ var h = this.pageToPosition(page);
+ // update the page
+ this.updateForPosition(h);
+ // call pageToPosition again and this time should return the right pos since the page info is populated
+ h = this.pageToPosition(page);
+ this.setScrollPosition(h);
+ if (page == this.p0 || page == this.p1) {
+ var rowNode = this.$.generator.fetchRowNode(inRow);
+ if (rowNode) {
+ // calc row offset
+ var offset = rowNode.offsetTop;
+ if (this.bottomUp) {
+ offset = this.getPageHeight(page) - rowNode.offsetHeight - offset;
+ }
+ var y = this.getScrollPosition() + offset;
+ this.setScrollPosition(y);
+ }
+ }
+ },
+ //* Scrolls to the beginning of the list.
+ scrollToStart: function() {
+ this[this.bottomUp ? "scrollToBottom" : "scrollToTop"]();
+ },
+ //* Scrolls to the end of the list.
+ scrollToEnd: function() {
+ this[this.bottomUp ? "scrollToTop" : "scrollToBottom"]();
+ },
+ //* Re-renders the list at the current position.
+ refresh: function() {
+ this.invalidatePages();
+ this.update(this.getScrollTop());
+ this.stabilize();
+
+ //FIXME: Necessary evil for Android 4.0.4 refresh bug
+ if (enyo.platform.android === 4) {
+ this.twiddle();
+ }
+ },
+ /**
+ Re-renders the list from the beginning. This is used when changing the
+ data model for the list. This also clears the selection state.
+ */
+ reset: function() {
+ this.getSelection().clear();
+ this.invalidateMetrics();
+ this.invalidatePages();
+ this.stabilize();
+ this.scrollToStart();
+ },
+ /**
+ Returns the [enyo.Selection](#enyo.Selection) component that
+ manages the selection state for this list.
+ */
+ getSelection: function() {
+ return this.$.generator.getSelection();
+ },
+ /**
+ Sets the selection state for the given row index.
+ _inData_ is an optional data value stored in the selection object.
+
+ Modifying selection will not automatically rerender the row,
+ so use [renderRow](#enyo.List::renderRow) or [refresh](#enyo.List::refresh)
+ to update the view.
+ */
+ select: function(inIndex, inData) {
+ return this.getSelection().select(inIndex, inData);
+ },
+ /**
+ Clears the selection state for the given row index.
+
+ Modifying selection will not automatically re-render the row,
+ so use [renderRow](#enyo.List::renderRow) or [refresh](#enyo.List::refresh)
+ to update the view.
+ */
+ deselect: function(inIndex) {
+ return this.getSelection().deselect(inIndex);
+ },
+ //* Gets the selection state for the given row index.
+ isSelected: function(inIndex) {
+ return this.$.generator.isSelected(inIndex);
+ },
+ /**
+ Re-renders the specified row. Call this method after making
+ modifications to a row, to force it to render.
+ */
+ renderRow: function(inIndex) {
+ this.$.generator.renderRow(inIndex);
+ },
+ //* Updates row bounds when rows are re-rendered.
+ rowRendered: function(inSender, inEvent) {
+ this.updateRowBounds(inEvent.rowIndex);
+ },
+ //* Prepares the row to become interactive.
+ prepareRow: function(inIndex) {
+ this.$.generator.prepareRow(inIndex);
+ },
+ //* Restores the row to being non-interactive.
+ lockRow: function() {
+ this.$.generator.lockRow();
+ },
+ /**
+ Performs a set of tasks by running the function _inFunc_ on a row (which
+ must be interactive at the time the tasks are performed). Locks the row
+ when done.
+ */
+ performOnRow: function(inIndex, inFunc, inContext) {
+ this.$.generator.performOnRow(inIndex, inFunc, inContext);
+ },
+ //* @protected
+ animateFinish: function(inSender) {
+ this.twiddle();
+ return true;
+ },
+ // FIXME: Android 4.04 has issues with nested composited elements; for example, a SwipeableItem,
+ // can incorrectly generate taps on its content when it has slid off the screen;
+ // we address this BUG here by forcing the Scroller to "twiddle" which corrects the bug by
+ // provoking a dom update.
+ twiddle: function() {
+ var s = this.getStrategy();
+ enyo.call(s, "twiddle");
+ },
+ // return page0 or page1 control depending on pageNumber odd/even status
+ pageForPageNumber: function(pageNumber, checkRange) {
+ if (pageNumber % 2 === 0) {
+ return (!checkRange || (pageNumber === this.p0)) ? this.$.page0 : null;
+ }
+ else {
+ return (!checkRange || (pageNumber === this.p1)) ? this.$.page1 : null;
+ }
+ return null;
+ },
+ /**
+ ---- Reorder functionality ------------
+ */
+ //* Determines whether we should handle the hold event as a reorder hold.
+ shouldStartReordering: function(inSender, inEvent) {
+ if(!this.getReorderable() || !(inEvent.rowIndex >= 0) || this.pinnedReorderMode ||
+ inSender !== this.$.strategy || !(inEvent.index >= 0)) {
+ return false;
+ }
+ return true;
+ },
+ //* Processes hold event and prepares for reordering.
+ startReordering: function(inEvent) {
+ // disable drag to scroll on strategy
+ this.$.strategy.listReordering = true;
+
+ this.buildReorderContainer();
+ this.doSetupReorderComponents(inEvent);
+ this.styleReorderContainer(inEvent);
+
+ this.draggingRowIndex = this.placeholderRowIndex = inEvent.rowIndex;
+ this.draggingRowNode = inEvent.target;
+ this.removedInitialPage = false;
+ this.itemMoved = false;
+ this.initialPageNumber = this.currentPageNumber = this.pageForRow(inEvent.rowIndex);
+ this.prevScrollTop = this.getScrollTop();
+
+ // fill row being reordered with placeholder
+ this.replaceNodeWithPlaceholder(inEvent.rowIndex);
+ },
+ /**
+ Fills reorder container with draggable reorder components defined by the
+ application.
+ */
+ buildReorderContainer: function() {
+ this.$.reorderContainer.destroyClientControls();
+ for(var i=0;i<this.reorderComponents.length;i++) {
+ this.$.reorderContainer.createComponent(this.reorderComponents[i], {owner:this.owner});
+ }
+ this.$.reorderContainer.render();
+ },
+ //* Prepares floating reorder container.
+ styleReorderContainer: function(e) {
+ this.setItemPosition(this.$.reorderContainer, e.rowIndex);
+ this.setItemBounds(this.$.reorderContainer, e.rowIndex);
+ this.$.reorderContainer.setShowing(true);
+ if (this.centerReorderContainer) {
+ this.centerReorderContainerOnPointer(e);
+ }
+ },
+ //* Copies the innerHTML of _node_ into a new component inside of
+ //* _reorderContainer_.
+ appendNodeToReorderContainer: function(node) {
+ this.$.reorderContainer.createComponent({allowHtml: true, content: node.innerHTML}).render();
+ },
+ //* Centers the floating reorder container on the user's pointer.
+ centerReorderContainerOnPointer: function(e) {
+ var containerPosition = enyo.dom.calcNodePosition(this.hasNode());
+ var x = e.pageX - containerPosition.left - parseInt(this.$.reorderContainer.domStyles.width, 10)/2;
+ var y = e.pageY - containerPosition.top + this.getScrollTop() - parseInt(this.$.reorderContainer.domStyles.height, 10)/2;
+ if(this.getStrategyKind() != "ScrollStrategy") {
+ x -= this.getScrollLeft();
+ y -= this.getScrollTop();
+ }
+ this.positionReorderContainer(x,y);
+ },
+ /**
+ Moves the reorder container to the specified _x_ and _y_ coordinates.
+ Animates and kicks off timer to turn off animation.
+ */
+ positionReorderContainer: function(x,y) {
+ this.$.reorderContainer.addClass("enyo-animatedTopAndLeft");
+ this.$.reorderContainer.addStyles("left:"+x+"px;top:"+y+"px;");
+ this.setPositionReorderContainerTimeout();
+ },
+ setPositionReorderContainerTimeout: function() {
+ this.clearPositionReorderContainerTimeout();
+ this.positionReorderContainerTimeout = setTimeout(enyo.bind(this,
+ function() {
+ this.$.reorderContainer.removeClass("enyo-animatedTopAndLeft");
+ this.clearPositionReorderContainerTimeout();
+ }), 100);
+ },
+ clearPositionReorderContainerTimeout: function() {
+ if(this.positionReorderContainerTimeout) {
+ clearTimeout(this.positionReorderContainerTimeout);
+ this.positionReorderContainerTimeout = null;
+ }
+ },
+ //* Determines whether we should handle the drag event.
+ shouldDoReorderDrag: function() {
+ if(!this.getReorderable() || this.draggingRowIndex < 0 || this.pinnedReorderMode) {
+ return false;
+ }
+ return true;
+ },
+ //* Handles the drag event as a reorder drag.
+ reorderDrag: function(inEvent) {
+ // position reorder node under mouse/pointer
+ this.positionReorderNode(inEvent);
+
+ // determine if we need to auto-scroll the list
+ this.checkForAutoScroll(inEvent);
+
+ // if the current index the user is dragging over has changed, move the placeholder
+ this.updatePlaceholderPosition(inEvent.pageY);
+ },
+ updatePlaceholderPosition: function(pageY) {
+ var index = this.getRowIndexFromCoordinate(pageY);
+ if (index !== -1) {
+ // cursor moved over a new row, so determine direction of movement
+ if (index >= this.placeholderRowIndex) {
+ this.movePlaceholderToIndex(Math.min(this.count, index + 1));
+ }
+ else {
+ this.movePlaceholderToIndex(index);
+ }
+ }
+ },
+ //* Positions the reorder node based on the dx and dy of the drag event.
+ positionReorderNode: function(e) {
+ var reorderNodeBounds = this.$.reorderContainer.getBounds();
+ var left = reorderNodeBounds.left + e.ddx;
+ var top = reorderNodeBounds.top + e.ddy;
+ top = (this.getStrategyKind() == "ScrollStrategy") ? top + (this.getScrollTop() - this.prevScrollTop) : top;
+ this.$.reorderContainer.addStyles("top: "+top+"px ; left: "+left+"px");
+ this.prevScrollTop = this.getScrollTop();
+ },
+ /**
+ Checks if the list should scroll when dragging and, if so, starts the
+ scroll timeout timer. Auto-scrolling happens when the user drags an item
+ within the top/bottom boundary percentage defined in
+ _this.dragToScrollThreshold_.
+ */
+ checkForAutoScroll: function(inEvent) {
+ var position = enyo.dom.calcNodePosition(this.hasNode());
+ var bounds = this.getBounds();
+ var perc;
+ this.autoscrollPageY = inEvent.pageY;
+ if(inEvent.pageY - position.top < bounds.height * this.dragToScrollThreshold) {
+ perc = 100*(1 - ((inEvent.pageY - position.top) / (bounds.height * this.dragToScrollThreshold)));
+ this.scrollDistance = -1*perc;
+ } else if(inEvent.pageY - position.top > bounds.height * (1 - this.dragToScrollThreshold)) {
+ perc = 100*((inEvent.pageY - position.top - bounds.height*(1 - this.dragToScrollThreshold)) / (bounds.height - (bounds.height * (1 - this.dragToScrollThreshold))));
+ this.scrollDistance = 1*perc;
+ } else {
+ this.scrollDistance = 0;
+ }
+ // stop scrolling if distance is zero (i.e., user isn't scrolling to the edges of
+ // the list); otherwise, start it if not already started
+ if (this.scrollDistance === 0) {
+ this.stopAutoScrolling();
+ } else {
+ if(!this.autoScrollTimeout) {
+ this.startAutoScrolling();
+ }
+ }
+ },
+ //* Stops auto-scrolling.
+ stopAutoScrolling: function() {
+ if(this.autoScrollTimeout) {
+ clearTimeout(this.autoScrollTimeout);
+ this.autoScrollTimeout = null;
+ }
+ },
+ //* Starts auto-scrolling.
+ startAutoScrolling: function() {
+ this.autoScrollTimeout = setInterval(enyo.bind(this, this.autoScroll), this.autoScrollTimeoutMS);
+ },
+ //* Scrolls the list by the distance specified in _this.scrollDistance_.
+ autoScroll: function() {
+ if(this.scrollDistance === 0) {
+ this.stopAutoScrolling();
+ } else {
+ if(!this.autoScrollTimeout) {
+ this.startAutoScrolling();
+ }
+ }
+ this.setScrollPosition(this.getScrollPosition() + this.scrollDistance);
+ this.positionReorderNode({ddx: 0, ddy: 0});
+
+ // if the current index the user is dragging over has changed, move the placeholder
+ this.updatePlaceholderPosition(this.autoscrollPageY);
+ },
+ /**
+ Moves the placeholder (i.e., the gap between rows) to the row currently
+ under the user's pointer. This provides a visual cue, showing the user
+ where the item being dragged will go if it is dropped.
+ */
+ movePlaceholderToIndex: function(index) {
+ var node, nodeParent;
+ if (index < 0) {
+ return;
+ }
+ else if (index >= this.count) {
+ node = null;
+ nodeParent = this.pageForPageNumber(this.pageForRow(this.count - 1)).hasNode();
+ }
+ else {
+ node = this.$.generator.fetchRowNode(index);
+ nodeParent = node.parentNode;
+ }
+ // figure next page for placeholder
+ var nextPageNumber = this.pageForRow(index);
+
+ // don't add pages beyond the original page count
+ if(nextPageNumber >= this.pageCount) {
+ nextPageNumber = this.currentPageNumber;
+ }
+
+ // move the placeholder to just after our "index" node
+ nodeParent.insertBefore(
+ this.placeholderNode,
+ node);
+
+ if(this.currentPageNumber !== nextPageNumber) {
+ // if moving to different page, recalculate page heights and reposition pages
+ this.updatePageHeight(this.currentPageNumber);
+ this.updatePageHeight(nextPageNumber);
+ this.updatePagePositions(nextPageNumber);
+ }
+
+ // save updated state
+ this.placeholderRowIndex = index;
+ this.currentPageNumber = nextPageNumber;
+
+ // remember that we moved an item (to prevent pinning at the wrong time)
+ this.itemMoved = true;
+ },
+ /**
+ Turns off reordering. If the user didn't drag the item being reordered
+ outside of its original position, goes into pinned reorder mode.
+ */
+ finishReordering: function(inSender, inEvent) {
+ if(!this.isReordering() || this.pinnedReorderMode || this.completeReorderTimeout) {
+ return;
+ }
+ this.stopAutoScrolling();
+ // enable drag-scrolling on strategy
+ this.$.strategy.listReordering = false;
+ // animate reorder container to proper position and then complete
+ // reordering actions
+ this.moveReorderedContainerToDroppedPosition(inEvent);
+ this.completeReorderTimeout = setTimeout(
+ enyo.bind(this, this.completeFinishReordering, inEvent), 100);
+
+ inEvent.preventDefault();
+ return true;
+ },
+ //*
+ moveReorderedContainerToDroppedPosition: function() {
+ var offset = this.getRelativeOffset(this.placeholderNode, this.hasNode());
+ var top = (this.getStrategyKind() == "ScrollStrategy") ? offset.top : offset.top - this.getScrollTop();
+ var left = offset.left - this.getScrollLeft();
+ this.positionReorderContainer(left,top);
+ },
+ /**
+ After the reordered item has been animated to its position, completes
+ the reordering logic.
+ */
+ completeFinishReordering: function(inEvent) {
+ this.completeReorderTimeout = null;
+ // adjust placeholderRowIndex to now be the final resting place
+ if (this.placeholderRowIndex > this.draggingRowIndex) {
+ this.placeholderRowIndex = Math.max(0, this.placeholderRowIndex - 1);
+ }
+ // if the user dropped the item in the same location where it was picked up, and they
+ // didn't move any other items in the process, pin the item and go into pinned reorder mode
+ if(this.draggingRowIndex == this.placeholderRowIndex &&
+ this.pinnedReorderComponents.length && !this.pinnedReorderMode && !this.itemMoved) {
+ this.beginPinnedReorder(inEvent);
+ return;
+ }
+ this.removeDraggingRowNode();
+ this.removePlaceholderNode();
+ this.emptyAndHideReorderContainer();
+ // clear this early to prevent scroller code from using disappeared placeholder
+ this.pinnedReorderMode = false;
+ this.reorderRows(inEvent);
+ this.draggingRowIndex = this.placeholderRowIndex = -1;
+ this.refresh();
+ },
+ //* Go into pinned reorder mode
+ beginPinnedReorder: function(e) {
+ this.buildPinnedReorderContainer();
+ this.doSetupPinnedReorderComponents(enyo.mixin(e, {index: this.draggingRowIndex}));
+ this.pinnedReorderMode = true;
+ this.initialPinPosition = e.pageY;
+ },
+ //* Clears contents of reorder container, then hides.
+ emptyAndHideReorderContainer: function() {
+ this.$.reorderContainer.destroyComponents();
+ this.$.reorderContainer.setShowing(false);
+ },
+ //* Fills reorder container with pinned controls.
+ buildPinnedReorderContainer: function() {
+ this.$.reorderContainer.destroyClientControls();
+ for(var i=0;i<this.pinnedReorderComponents.length;i++) {
+ this.$.reorderContainer.createComponent(this.pinnedReorderComponents[i], {owner:this.owner});
+ }
+ this.$.reorderContainer.render();
+ },
+ //* Swaps the rows that were reordered, and sends up reorder event.
+ reorderRows: function(inEvent) {
+ // send reorder event
+ this.doReorder(this.makeReorderEvent(inEvent));
+ // update display
+ this.positionReorderedNode();
+ // fix indices for reordered rows
+ this.updateListIndices();
+ },
+ //* Adds _reorderTo_ and _reorderFrom_ properties to the reorder event.
+ makeReorderEvent: function(e) {
+ e.reorderFrom = this.draggingRowIndex;
+ e.reorderTo = this.placeholderRowIndex;
+ return e;
+ },
+ //* Moves the node being reordered to its new position and shows it.
+ positionReorderedNode: function() {
+ // only do this if the page with the initial item is still rendered
+ if (!this.removedInitialPage) {
+ var insertNode = this.$.generator.fetchRowNode(this.placeholderRowIndex);
+ if (insertNode) {
+ insertNode.parentNode.insertBefore(this.hiddenNode, insertNode);
+ this.showNode(this.hiddenNode);
+ }
+ this.hiddenNode = null;
+ if (this.currentPageNumber != this.initialPageNumber) {
+ var mover, movee;
+ var currentPage = this.pageForPageNumber(this.currentPageNumber);
+ var otherPage = this.pageForPageNumber(this.currentPageNumber + 1);
+ // if moved down, move current page's firstChild to the end of previous page
+ if (this.initialPageNumber < this.currentPageNumber) {
+ mover = currentPage.hasNode().firstChild;
+ otherPage.hasNode().appendChild(mover);
+ // if moved up, move current page's lastChild before previous page's firstChild
+ } else {
+ mover = currentPage.hasNode().lastChild;
+ movee = otherPage.hasNode().firstChild;
+ otherPage.hasNode().insertBefore(mover, movee);
+ }
+ this.correctPageHeights();
+ this.updatePagePositions(this.initialPageNumber);
+ }
+ }
+ },
+ //* Updates indices of list items as needed to preserve reordering.
+ updateListIndices: function() {
+ // don't do update if we've moved further than one page, refresh instead
+ if(this.shouldDoRefresh()) {
+ this.refresh();
+ this.correctPageHeights();
+ return;
+ }
+
+ var from = Math.min(this.draggingRowIndex, this.placeholderRowIndex);
+ var to = Math.max(this.draggingRowIndex, this.placeholderRowIndex);
+ var direction = (this.draggingRowIndex - this.placeholderRowIndex > 0) ? 1 : -1;
+ var node, i, newIndex, currentIndex;
+
+ if(direction === 1) {
+ node = this.$.generator.fetchRowNode(this.draggingRowIndex);
+ if (node) {
+ node.setAttribute("data-enyo-index", "reordered");
+ }
+ for(i=(to-1),newIndex=to;i>=from;i--) {
+ node = this.$.generator.fetchRowNode(i);
+ if(!node) {
+ continue;
+ }
+ currentIndex = parseInt(node.getAttribute("data-enyo-index"), 10);
+ newIndex = currentIndex + 1;
+ node.setAttribute("data-enyo-index", newIndex);
+ }
+ node = this.hasNode().querySelector('[data-enyo-index="reordered"]');
+ node.setAttribute("data-enyo-index", this.placeholderRowIndex);
+
+ } else {
+ node = this.$.generator.fetchRowNode(this.draggingRowIndex);
+ if (node) {
+ node.setAttribute("data-enyo-index", this.placeholderRowIndex);
+ }
+ for(i=(from+1), newIndex=from;i<=to;i++) {
+ node = this.$.generator.fetchRowNode(i);
+ if(!node) {
+ continue;
+ }
+ currentIndex = parseInt(node.getAttribute("data-enyo-index"), 10);
+ newIndex = currentIndex - 1;
+ node.setAttribute("data-enyo-index", newIndex);
+ }
+ }
+ },
+ //* Determines if an item was reordered far enough that it warrants a refresh.
+ shouldDoRefresh: function() {
+ return (Math.abs(this.initialPageNumber - this.currentPageNumber) > 1);
+ },
+ //* Gets node height, width, top, and left values.
+ getNodeStyle: function(index) {
+ var node = this.$.generator.fetchRowNode(index);
+ if(!node) {
+ return;
+ }
+ var offset = this.getRelativeOffset(node, this.hasNode());
+ var dimensions = enyo.dom.getBounds(node);
+ return {h: dimensions.height, w: dimensions.width, left: offset.left, top: offset.top};
+ },
+ //* Gets offset relative to a positioned ancestor node.
+ getRelativeOffset: function (n, p) {
+ var ro = {top: 0, left: 0};
+ if (n !== p && n.parentNode) {
+ do {
+ ro.top += n.offsetTop || 0;
+ ro.left += n.offsetLeft || 0;
+ n = n.offsetParent;
+ } while (n && n !== p);
+ }
+ return ro;
+ },
+ replaceNodeWithPlaceholder: function(index) {
+ var node = this.$.generator.fetchRowNode(index);
+ if(!node) {
+ enyo.log("No node - "+index);
+ return;
+ }
+ // create and style placeholder node
+ this.placeholderNode = this.createPlaceholderNode(node);
+ // hide existing node
+ this.hiddenNode = this.hideNode(node);
+ // insert placeholder node where original node was
+ var currentPage = this.pageForPageNumber(this.currentPageNumber);
+ currentPage.hasNode().insertBefore(this.placeholderNode,this.hiddenNode);
+ },
+ /**
+ Creates and returns a placeholder node with dimensions matching those of
+ the passed-in node.
+ */
+ createPlaceholderNode: function(node) {
+ var placeholderNode = this.$.placeholder.hasNode().cloneNode(true);
+ var nodeDimensions = enyo.dom.getBounds(node);
+ placeholderNode.style.height = nodeDimensions.height + "px";
+ placeholderNode.style.width = nodeDimensions.width + "px";
+ return placeholderNode;
+ },
+ //* Removes the placeholder node from the DOM.
+ removePlaceholderNode: function() {
+ this.removeNode(this.placeholderNode);
+ this.placeholderNode = null;
+ },
+ removeDraggingRowNode: function() {
+ this.draggingRowNode = null;
+ var holdingArea = this.$.holdingarea.hasNode();
+ holdingArea.innerHTML = "";
+ },
+ //* Removes the passed-in node from the DOM.
+ removeNode: function(node) {
+ if(!node || !node.parentNode) {
+ return;
+ }
+ node.parentNode.removeChild(node);
+ },
+ /**
+ Updates _this.pageHeights_ to support the placeholder node's jumping
+ from one page to the next.
+ */
+ updatePageHeight: function(pageNumber) {
+ if (pageNumber < 0) {
+ return;
+ }
+ var pageControl = this.pageForPageNumber(pageNumber, true);
+ if (pageControl) {
+ var h0 = this.pageHeights[pageNumber];
+ var pageHeight = Math.max(1, pageControl.getBounds().height);
+ this.pageHeights[pageNumber] = pageHeight;
+ this.portSize += pageHeight - h0;
+ }
+ },
+ /**
+ Repositions the two passed-in pages to support the placeholder node's
+ jumping from one page to the next.
+ */
+ updatePagePositions: function(nextPageNumber) {
+ this.positionPage(this.currentPageNumber, this.pageForPageNumber(this.currentPageNumber));
+ this.positionPage(nextPageNumber, this.pageForPageNumber(nextPageNumber));
+ },
+ //* Corrects page heights array after reorder is complete.
+ correctPageHeights: function() {
+ this.updatePageHeight(this.currentPageNumber);
+ if (this.initialPageNumber != this.currentPageNumber) {
+ this.updatePageHeight(this.initialPageNumber);
+ }
+ },
+ hideNode: function(node) {
+ node.style.display = "none";
+ return node;
+ },
+ showNode: function(node) {
+ node.style.display = "block";
+ return node;
+ },
+ //* @public
+ //* Called by client code to finalize a pinned mode reordering, such as when the "Drop" button is pressed
+ //* on the pinned placeholder row.
+ dropPinnedRow: function(inEvent) {
+ // animate reorder container to proper position and then complete reording actions
+ this.moveReorderedContainerToDroppedPosition(inEvent);
+ this.completeReorderTimeout = setTimeout(
+ enyo.bind(this, this.completeFinishReordering, inEvent), 100);
+ return;
+ },
+ cancelPinnedMode: function(inEvent) {
+ // make it look like we're dropping in original location
+ this.placeholderRowIndex = this.draggingRowIndex;
+ this.dropPinnedRow(inEvent);
+ },
+ //* @protected
+ //* Returns the row index that is under the given position on the page. If the
+ //* position is off the end of the list, this will return this.count. If the position
+ //* is before the start of the list, you'll get -1.
+ getRowIndexFromCoordinate: function(y) {
+ var cursorPosition = this.getScrollTop() + y - enyo.dom.calcNodePosition(this.hasNode()).top;
+ // happens if we try to drag past top of list
+ if (cursorPosition < 0) {
+ return -1;
+ }
+ var pageInfo = this.positionToPageInfo(cursorPosition);
+ var rows = (pageInfo.no == this.p0) ? this.p0RowBounds : this.p1RowBounds;
+ // might have only rendered one page, so catch that here
+ if (!rows) {
+ return this.count;
+ }
+ var posOnPage = pageInfo.pos;
+ var placeholderHeight = this.placeholderNode ? enyo.dom.getBounds(this.placeholderNode).height : 0;
+ var totalHeight = 0;
+ for(var i=pageInfo.startRow; i <= pageInfo.endRow; ++i) {
+ // do extra check for row that has placeholder as we'll return -1 here for no match
+ if (i === this.placeholderRowIndex) {
+ // for placeholder
+ totalHeight += placeholderHeight;
+ if(totalHeight >= posOnPage) {
+ return -1;
+ }
+ }
+ // originally dragged row is hidden, so don't count it
+ if (i !== this.draggingRowIndex) {
+ totalHeight += rows[i].height;
+ if(totalHeight >= posOnPage) {
+ return i;
+ }
+ }
+ }
+ return i;
+ },
+ //* Gets the position of a node (identified via index) on the page.
+ getIndexPosition: function(index) {
+ return enyo.dom.calcNodePosition(this.$.generator.fetchRowNode(index));
+ },
+ //* Sets _$item_'s position to match that of the list row at _index_.
+ setItemPosition: function($item,index) {
+ var clonedNodeStyle = this.getNodeStyle(index);
+ var top = (this.getStrategyKind() == "ScrollStrategy") ? clonedNodeStyle.top : clonedNodeStyle.top - this.getScrollTop();
+ var styleStr = "top:"+top+"px; left:"+clonedNodeStyle.left+"px;";
+ $item.addStyles(styleStr);
+ },
+ //* Sets _$item_'s width and height to match those of the list row at _index_.
+ setItemBounds: function($item,index) {
+ var clonedNodeStyle = this.getNodeStyle(index);
+ var styleStr = "width:"+clonedNodeStyle.w+"px; height:"+clonedNodeStyle.h+"px;";
+ $item.addStyles(styleStr);
+ },
+ /**
+ When in pinned reorder mode, repositions the pinned placeholder when the
+ user has scrolled far enough.
+ */
+ reorderScroll: function(inSender, e) {
+ // if we are using the standard scroll strategy, we have to move the pinned row with the scrolling
+ if(this.getStrategyKind() == "ScrollStrategy") {
+ this.$.reorderContainer.addStyles("top:"+(this.initialPinPosition+this.getScrollTop()-this.rowHeight)+"px;");
+ }
+ // y coordinate on screen of the pinned item doesn't change as we scroll things
+ this.updatePlaceholderPosition(this.initialPinPosition);
+ },
+ hideReorderingRow: function() {
+ var hiddenNode = this.hasNode().querySelector('[data-enyo-index="'+this.draggingRowIndex+'"]');
+ // hide existing node
+ if(hiddenNode) {
+ this.hiddenNode = this.hideNode(hiddenNode);
+ }
+ },
+ isReordering: function() {
+ return (this.draggingRowIndex > -1);
+ },
+
+ /**
+ ---- Swipeable functionality ------------
+ */
+
+ isSwiping: function() {
+ // we're swiping when the index is set and we're not in the middle of completing or backing out a swipe
+ return (this.swipeIndex != null && !this.swipeComplete && this.swipeDirection != null);
+ },
+ /**
+ When a drag starts, gets the direction of the drag as well as the index
+ of the item being dragged, and resets any pertinent values. Then kicks
+ off the swipe sequence.
+ */
+ swipeDragStart: function(inSender, inEvent) {
+ // if we're not on a row or the swipe is vertical or if we're in the middle of reordering, just say no
+ if(inEvent.index == null || inEvent.vertical) {
+ return true;
+ }
+
+ // if we are waiting to complete a swipe, complete it
+ if(this.completeSwipeTimeout) {
+ this.completeSwipe(inEvent);
+ }
+
+ // reset swipe complete flag
+ this.swipeComplete = false;
+
+ if (this.swipeIndex != inEvent.index) {
+ this.clearSwipeables();
+ this.swipeIndex = inEvent.index;
+ }
+ this.swipeDirection = inEvent.xDirection;
+
+ // start swipe sequence only if we are not currently showing a persistent item
+ if(!this.persistentItemVisible) {
+ this.startSwipe(inEvent);
+ }
+
+ // reset dragged distance (for dragfinish)
+ this.draggedXDistance = 0;
+ this.draggedYDistance = 0;
+
+ return true;
+ },
+ /**
+ When a drag is in progress, updates the position of the swipeable
+ container based on the ddx of the event.
+ */
+ swipeDrag: function(inSender, inEvent) {
+ // if a persistent swipeableItem is still showing, handle it separately
+ if (this.persistentItemVisible) {
+ this.dragPersistentItem(inEvent);
+ return this.preventDragPropagation;
+ }
+ // early exit if there's no matching dragStart to set item
+ if (!this.isSwiping()) {
+ return false;
+ }
+ // apply new position
+ this.dragSwipeableComponents(this.calcNewDragPosition(inEvent.ddx));
+ // save dragged distance (for dragfinish)
+ this.draggedXDistance = inEvent.dx;
+ this.draggedYDistance = inEvent.dy;
+ return true;
+ },
+ /*
+ When the current drag completes, decides whether to complete the swipe
+ based on how far the user pulled the swipeable container.
+ */
+ swipeDragFinish: function(inSender, inEvent) {
+ // if a persistent swipeableItem is still showing, complete drag away or bounce
+ if (this.persistentItemVisible) {
+ this.dragFinishPersistentItem(inEvent);
+ // early exit if there's no matching dragStart to set item
+ } else if (!this.isSwiping()) {
+ return false;
+ // otherwise if user dragged more than 20% of the width, complete the swipe. if not, back out.
+ } else {
+ var percentageDragged = this.calcPercentageDragged(this.draggedXDistance);
+ if ((percentageDragged > this.percentageDraggedThreshold) && (inEvent.xDirection === this.swipeDirection)) {
+ this.swipe(this.fastSwipeSpeedMS);
+ } else {
+ this.backOutSwipe(inEvent);
+ }
+ }
+
+ return this.preventDragPropagation;
+ },
+ // reorder takes precedence over swipes, and not having it turned on or swipeable controls defined also disables this
+ isSwipeable: function() {
+ return this.enableSwipe && this.$.swipeableComponents.controls.length !== 0 &&
+ !this.isReordering() && !this.pinnedReorderMode;
+ },
+ // Positions the swipeable components block at the current row.
+ positionSwipeableContainer: function(index,xDirection) {
+ var node = this.$.generator.fetchRowNode(index);
+ if(!node) {
+ return;
+ }
+ var offset = this.getRelativeOffset(node, this.hasNode());
+ var dimensions = enyo.dom.getBounds(node);
+ var x = (xDirection == 1) ? -1*dimensions.width : dimensions.width;
+ this.$.swipeableComponents.addStyles("top: "+offset.top+"px; left: "+x+"px; height: "+dimensions.height+"px; width: "+dimensions.width+"px;");
+ },
+ /**
+ Calculates new position for the swipeable container based on the user's
+ drag action. Don't allow the container to drag beyond either edge.
+ */
+ calcNewDragPosition: function(dx) {
+ var parentBounds = this.$.swipeableComponents.getBounds();
+ var xPos = parentBounds.left;
+ var dimensions = this.$.swipeableComponents.getBounds();
+ var xlimit = (this.swipeDirection == 1) ? 0 : -1*dimensions.width;
+ var x = (this.swipeDirection == 1)
+ ? (xPos + dx > xlimit)
+ ? xlimit
+ : xPos + dx
+ : (xPos + dx < xlimit)
+ ? xlimit
+ : xPos + dx;
+ return x;
+ },
+ dragSwipeableComponents: function(x) {
+ this.$.swipeableComponents.applyStyle("left",x+"px");
+ },
+ /**
+ Begins swiping sequence by positioning the swipeable container and
+ bubbling the setupSwipeItem event.
+ */
+ startSwipe: function(e) {
+ // modify event index to always have this swipeItem value
+ e.index = this.swipeIndex;
+ this.positionSwipeableContainer(this.swipeIndex,e.xDirection);
+ this.$.swipeableComponents.setShowing(true);
+ this.setPersistentItemOrigin(e.xDirection);
+ this.doSetupSwipeItem(e);
+ },
+ // If a persistent swipeableItem is still showing, drags it away or bounces it.
+ dragPersistentItem: function(e) {
+ var xPos = 0;
+ var x = (this.persistentItemOrigin == "right")
+ ? Math.max(xPos, (xPos + e.dx))
+ : Math.min(xPos, (xPos + e.dx));
+ this.$.swipeableComponents.applyStyle("left",x+"px");
+ },
+ // If a persistent swipeableItem is still showing, completes drag away or bounce.
+ dragFinishPersistentItem: function(e) {
+ var completeSwipe = (this.calcPercentageDragged(e.dx) > 0.2);
+ var dir = (e.dx > 0) ? "right" : (e.dx < 0) ? "left" : null;
+ if(this.persistentItemOrigin == dir) {
+ if(completeSwipe) {
+ this.slideAwayItem();
+ } else {
+ this.bounceItem(e);
+ }
+ } else {
+ this.bounceItem(e);
+ }
+ },
+ setPersistentItemOrigin: function(xDirection) {
+ this.persistentItemOrigin = xDirection == 1 ? "left" : "right";
+ },
+ calcPercentageDragged: function(dx) {
+ return Math.abs(dx/this.$.swipeableComponents.getBounds().width);
+ },
+ swipe: function(speed) {
+ this.swipeComplete = true;
+ this.animateSwipe(0,speed);
+ },
+ backOutSwipe: function(e) {
+ var dimensions = this.$.swipeableComponents.getBounds();
+ var x = (this.swipeDirection == 1) ? -1*dimensions.width : dimensions.width;
+ this.animateSwipe(x,this.fastSwipeSpeedMS);
+ this.swipeDirection = null;
+ },
+ bounceItem: function(e) {
+ var bounds = this.$.swipeableComponents.getBounds();
+ if(bounds.left != bounds.width) {
+ this.animateSwipe(0,this.normalSwipeSpeedMS);
+ }
+ },
+ slideAwayItem: function() {
+ var $item = this.$.swipeableComponents;
+ var parentWidth = $item.getBounds().width;
+ var xPos = (this.persistentItemOrigin == "left") ? -1*parentWidth : parentWidth;
+ this.animateSwipe(xPos,this.normalSwipeSpeedMS);
+ this.persistentItemVisible = false;
+ this.setPersistSwipeableItem(false);
+ },
+ clearSwipeables: function() {
+ this.$.swipeableComponents.setShowing(false);
+ this.persistentItemVisible = false;
+ this.setPersistSwipeableItem(false);
+ },
+ // Completes swipe and hides active swipeable item.
+ completeSwipe: function(e) {
+ if(this.completeSwipeTimeout) {
+ clearTimeout(this.completeSwipeTimeout);
+ this.completeSwipeTimeout = null;
+ }
+ // if this wasn't a persistent item, hide it upon completion and send swipe complete event
+ if(!this.getPersistSwipeableItem()) {
+ this.$.swipeableComponents.setShowing(false);
+ // if the swipe was completed, update the current row and bubble swipeComplete event
+ if(this.swipeComplete) {
+ this.doSwipeComplete({index: this.swipeIndex, xDirection: this.swipeDirection});
+ }
+ } else {
+ this.persistentItemVisible = true;
+ }
+ this.swipeIndex = null;
+ this.swipeDirection = null;
+ },
+ animateSwipe: function(targetX,totalTimeMS) {
+ var t0 = enyo.now(), t = 0;
+ var $item = this.$.swipeableComponents;
+ var origX = parseInt($item.domStyles.left,10);
+ var xDelta = targetX - origX;
+
+ this.stopAnimateSwipe();
+
+ var fn = enyo.bind(this, function() {
+ var t = enyo.now() - t0;
+ var percTimeElapsed = t/totalTimeMS;
+ var currentX = origX + (xDelta)*Math.min(percTimeElapsed,1);
+
+ // set new left
+ $item.applyStyle("left",currentX+"px");
+
+ // schedule next frame
+ this.job = enyo.requestAnimationFrame(fn);
+
+ // potentially override animation TODO
+
+ // go until we've hit our total time
+ if(t/totalTimeMS >= 1) {
+ this.stopAnimateSwipe();
+ this.completeSwipeTimeout = setTimeout(enyo.bind(this, function() {
+ this.completeSwipe();
+ }), this.completeSwipeDelayMS);
+ }
+ });
+
+ this.job = enyo.requestAnimationFrame(fn);
+ },
+ stopAnimateSwipe: function() {
+ if(this.job) {
+ this.job = enyo.cancelRequestAnimationFrame(this.job);
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsourcePulldownListcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/source/PulldownList.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/source/PulldownList.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/source/PulldownList.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+.enyo-list-pulldown {
+ position: absolute;
+ bottom: 100%;
+ left: 0;
+ right: 0;
+}
+
+.enyo-puller {
+ position: relative;
+ height: 50px;
+ font-size: 22px;
+ color: #444;
+ padding: 20px 0 0px 34px;
+}
+
+.enyo-puller-text {
+ position: absolute;
+ left: 80px;
+ top: 22px;
+}
+
+.enyo-puller-arrow {
+ position: relative;
+ background: #444;
+ width: 7px;
+ height: 28px;
+ transition: transform 0.3s;
+ -webkit-transition: -webkit-transform 0.3s;
+ -moz-transition: -moz-transform 0.3s;
+ -o-transition: -o-transform 0.3s;
+ -ms-transition: -ms-transform 0.3s;
+}
+
+.enyo-puller-arrow:after {
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ border: 10px solid transparent;
+ border-bottom-color: #444;
+ bottom: 100%;
+ left: 50%;
+ margin-left: -10px;
+}
+
+.enyo-puller-arrow-up {
+ transform: rotate(0deg);
+ -webkit-transform: rotate(0deg);
+ -moz-transform: rotate(0deg);
+ -o-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+}
+
+.enyo-puller-arrow-down {
+ transform: rotate(180deg);
+ -webkit-transform: rotate(180deg);
+ -moz-transform: rotate(180deg);
+ -o-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsourcePulldownListjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/source/PulldownList.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/source/PulldownList.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/source/PulldownList.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,202 @@
</span><ins>+/**
+_enyo.PulldownList_ is a list that provides a pull-to-refresh feature, which
+allows new data to be retrieved and updated in the list.
+
+PulldownList provides the _onPullRelease_ event to allow an application to start
+retrieving new data. The _onPullComplete_ event indicates that the pull is
+complete and it's time to update the list with the new data.
+
+ {name: "list", kind: "PulldownList", onSetupItem: "setupItem",
+ onPullRelease: "pullRelease", onPullComplete: "pullComplete",
+ components: [
+ {name: "item"}
+ ]}
+
+ pullRelease: function() {
+ this.search();
+ },
+ processSearchResults: function(inRequest, inResponse) {
+ this.results = inResponse.results;
+ this.$.list.setCount(this.results.length);
+ this.$.list.completePull();
+ },
+ pullComplete: function() {
+ this.$.list.reset();
+ }
+*/
+enyo.kind({
+ name: "enyo.PulldownList",
+ kind: "List",
+ //* @protected
+ // Sets touch to true in inherited Scroller kind for touch-based scrolling strategy
+ touch: true,
+ // The pull notification area at the top of the list
+ pully: null,
+ pulldownTools: [
+ {name: "pulldown", classes: "enyo-list-pulldown", components: [
+ {name: "puller", kind: "Puller"}
+ ]}
+ ],
+ events: {
+ //* Fires when user initiates a pull action.
+ onPullStart: "",
+ //* Fires when user cancels a pull action.
+ onPullCancel: "",
+ //* Fires while a pull action is in progress.
+ onPull: "",
+ //* Fires when the list is released following a pull action, indicating
+ //* that we are ready to retrieve data.
+ onPullRelease: "",
+ //* Fires when data retrieval is complete, indicating that the data is
+ //* is ready to be displayed.
+ onPullComplete: ""
+ },
+ handlers: {
+ onScrollStart: "scrollStartHandler",
+ onScrollStop: "scrollStopHandler",
+ ondragfinish: "dragfinish"
+ },
+ //* Message displayed when list is not being pulled
+ pullingMessage: "Pull down to refresh...",
+ //* Message displayed while a pull action is in progress
+ pulledMessage: "Release to refresh...",
+ //* Message displayed while data is being retrieved
+ loadingMessage: "Loading...",
+ //
+ pullingIconClass: "enyo-puller-arrow enyo-puller-arrow-down",
+ pulledIconClass: "enyo-puller-arrow enyo-puller-arrow-up",
+ loadingIconClass: "",
+ //* @protected
+ create: function() {
+ var p = {kind: "Puller", showing: false, text: this.loadingMessage, iconClass: this.loadingIconClass, onCreate: "setPully"};
+ this.listTools.splice(0, 0, p);
+ this.inherited(arguments);
+ this.setPulling();
+ },
+ initComponents: function() {
+ this.createChrome(this.pulldownTools);
+ this.accel = enyo.dom.canAccelerate();
+ this.translation = this.accel ? "translate3d" : "translate";
+ this.strategyKind = this.resetStrategyKind();
+ this.inherited(arguments);
+ },
+ // Temporarily use TouchScrollStrategy on iOS devices (see ENYO-1714)
+ resetStrategyKind: function() {
+ return (enyo.platform.android >= 3)
+ ? "TranslateScrollStrategy"
+ : "TouchScrollStrategy";
+ },
+ setPully: function(inSender, inEvent) {
+ this.pully = inEvent.originator;
+ },
+ scrollStartHandler: function() {
+ this.firedPullStart = false;
+ this.firedPull = false;
+ this.firedPullCancel = false;
+ },
+ scroll: function(inSender, inEvent) {
+ var r = this.inherited(arguments);
+ if (this.completingPull) {
+ this.pully.setShowing(false);
+ }
+ var s = this.getStrategy().$.scrollMath || this.getStrategy();
+ var over = -1*this.getScrollTop();
+ if (s.isInOverScroll() && over > 0) {
+ enyo.dom.transformValue(this.$.pulldown, this.translation, "0," + over + "px" + (this.accel ? ",0" : ""));
+ if (!this.firedPullStart) {
+ this.firedPullStart = true;
+ this.pullStart();
+ this.pullHeight = this.$.pulldown.getBounds().height;
+ }
+ if (over > this.pullHeight && !this.firedPull) {
+ this.firedPull = true;
+ this.firedPullCancel = false;
+ this.pull();
+ }
+ if (this.firedPull && !this.firedPullCancel && over < this.pullHeight) {
+ this.firedPullCancel = true;
+ this.firedPull = false;
+ this.pullCancel();
+ }
+ }
+ return r;
+ },
+ scrollStopHandler: function() {
+ if (this.completingPull) {
+ this.completingPull = false;
+ this.doPullComplete();
+ }
+ },
+ dragfinish: function() {
+ if (this.firedPull) {
+ var s = this.getStrategy().$.scrollMath || this.getStrategy();
+ s.setScrollY(-1*this.getScrollTop() - this.pullHeight);
+ this.pullRelease();
+ }
+ },
+ //* @public
+ //* Signals that the list should execute pull completion. This is usually
+ //* called after the application has received the new data.
+ completePull: function() {
+ this.completingPull = true;
+ var s = this.getStrategy().$.scrollMath || this.getStrategy();
+ s.setScrollY(this.pullHeight);
+ s.start();
+ },
+ //* @protected
+ pullStart: function() {
+ this.setPulling();
+ this.pully.setShowing(false);
+ this.$.puller.setShowing(true);
+ this.doPullStart();
+ },
+ pull: function() {
+ this.setPulled();
+ this.doPull();
+ },
+ pullCancel: function() {
+ this.setPulling();
+ this.doPullCancel();
+ },
+ pullRelease: function() {
+ this.$.puller.setShowing(false);
+ this.pully.setShowing(true);
+ this.doPullRelease();
+ },
+ setPulling: function() {
+ this.$.puller.setText(this.pullingMessage);
+ this.$.puller.setIconClass(this.pullingIconClass);
+ },
+ setPulled: function() {
+ this.$.puller.setText(this.pulledMessage);
+ this.$.puller.setIconClass(this.pulledIconClass);
+ }
+});
+
+enyo.kind({
+ name: "enyo.Puller",
+ classes: "enyo-puller",
+ published: {
+ text: "",
+ iconClass: ""
+ },
+ events: {
+ onCreate: ""
+ },
+ components: [
+ {name: "icon"},
+ {name: "text", tag: "span", classes: "enyo-puller-text"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.doCreate();
+ this.textChanged();
+ this.iconClassChanged();
+ },
+ textChanged: function() {
+ this.$.text.setContent(this.text);
+ },
+ iconClassChanged: function() {
+ this.$.icon.setClasses(this.iconClass);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsourcepackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/source/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/source/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/source/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+enyo.depends(
+ "FlyweightRepeater.js",
+ "List.css",
+ "List.js",
+ "PulldownList.css",
+ "PulldownList.js",
+ "AroundList.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutlistsourcewippackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/list/source/wip-package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/list/source/wip-package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/list/source/wip-package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+enyo.depends(
+ // Add wip controls here
+ "AlphaJumper.css",
+ "AlphaJumper.js",
+ "AlphaJumpList.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+enyo.depends(
+ "fittable",
+ "list",
+ "slideable",
+ "panels",
+ "tree",
+ "imageview"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelspackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+enyo.depends(
+ "source/"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssamplesPanelsFlickrSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsFlickrSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsFlickrSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsFlickrSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,72 @@
</span><ins>+.panels-sample-flickr-panels {
+ color: white;
+ background: #555;
+}
+.panels-sample-flickr-panels > * {
+ width: 320px;
+ box-shadow: -4px 0px 4px rgba(0,0,0,0.3);
+ -moz-box-shadow: -4px 0px 4px rgba(0,0,0,0.3);
+ -webkit-box-shadow: -4px 0px 4px rgba(0,0,0,0.3);
+}
+.panels-sample-flickr-item {
+ position: relative;
+ border-bottom: 1px solid #0E0E0E;
+ padding: 12px 16px;
+ background-color: #333333;
+}
+
+.panels-sample-flickr-item.onyx-selected {
+ background-color: MidnightBlue;
+}
+
+.panels-sample-flickr-title {
+ position: absolute;
+ top: 40px;
+ right: 0;
+ left: 100px;
+
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+.panels-sample-flickr-thumbnail {
+ width: 75px;
+ height: 75px;
+}
+.panels-sample-flickr-more-button {
+ color: white; margin: 10px;
+}
+.panels-sample-flickr-more-spinner {
+ vertical-align: middle;
+ margin: -4px 0 0 4px;
+}
+.panels-sample-flickr-center {
+ margin: auto;
+}
+.panels-sample-flickr-main {
+ background-color: #333;
+}
+.panels-sample-flickr-image {
+ box-sizing: border-box;
+ max-height: 90%;
+ max-width: 90%;
+ border: solid 5px #CCC;
+ box-shadow: 1px 1px 5px #999;
+ width: auto;
+ height: auto;
+}
+
+.panels-sample-flickr-image.wide {
+ width: 100%;
+}
+
+
+@media all and (max-width: 800px) {
+ .panels-sample-flickr-image.wide {
+ width: auto;
+ }
+}
+
+.panels-sample-flickr-image.tall {
+ height: 100%;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssamplesPanelsFlickrSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsFlickrSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsFlickrSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsFlickrSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Panels Flickr App Example</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/source/wip-package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="PanelsFlickrSample.css" rel="stylesheet">
+ <script src="PanelsFlickrSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.PanelsFlickrSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssamplesPanelsFlickrSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsFlickrSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsFlickrSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsFlickrSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,152 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.PanelsFlickrSample",
+ kind: "Panels",
+ classes: "panels-sample-flickr-panels enyo-unselectable enyo-fit",
+ arrangerKind: "CollapsingArranger",
+ components: [
+ {layoutKind: "FittableRowsLayout", components: [
+ {kind: "onyx.Toolbar", components: [
+ {kind: "onyx.InputDecorator", style: "width: 90%;", layoutKind: "FittableColumnsLayout", components: [
+ {name: "searchInput", fit: true, kind: "onyx.Input", value: "Japan", onchange: "search"},
+ {kind: "Image", src: "assets/search-input-search.png", style: "width: 20px; height: 20px;"}
+ ]},
+ {name: "searchSpinner", kind: "Image", src: "assets/spinner.gif", showing: false}
+ ]},
+ {kind: "List", fit: true, touch: true, onSetupItem: "setupItem", components: [
+ {name: "item", style: "padding: 10px;", classes: "panels-sample-flickr-item enyo-border-box", ontap: "itemTap", components: [
+ {name: "thumbnail", kind: "Image", classes: "panels-sample-flickr-thumbnail"},
+ {name: "title", classes: "panels-sample-flickr-title"}
+ ]},
+ {name: "more", style: "background-color: #323232;", components: [
+ {kind: "onyx.Button", content: "more photos", classes: "onyx-dark panels-sample-flickr-more-button", ontap: "more"},
+ {name: "moreSpinner", kind: "Image", src: "assets/spinner.gif", classes: "panels-sample-flickr-more-spinner"}
+ ]}
+ ]}
+ ]},
+ {name: "pictureView", fit: true, kind: "FittableRows", classes: "enyo-fit panels-sample-flickr-main", components: [
+ {name: "backToolbar", kind: "onyx.Toolbar", showing: false, components: [
+ {kind: "onyx.Button", content: "Back", ontap: "showList"}
+ ]},
+ {fit: true, style: "position: relative;", components: [
+ {name: "flickrImage", kind: "Image", classes: "enyo-fit panels-sample-flickr-center panels-sample-flickr-image", showing: false, onload: "imageLoaded", onerror: "imageLoaded"},
+ {name: "imageSpinner", kind: "Image", src: "assets/spinner-large.gif", classes: "enyo-fit panels-sample-flickr-center", showing: false}
+ ]}
+ ]},
+ {kind: "FlickrSearch", onResults: "searchResults"}
+ ],
+ rendered: function() {
+ this.inherited(arguments);
+ this.search();
+ },
+ reflow: function() {
+ this.inherited(arguments);
+ var backShowing = this.$.backToolbar.showing;
+ this.$.backToolbar.setShowing(enyo.Panels.isScreenNarrow());
+ if (this.$.backToolbar.showing != backShowing) {
+ this.$.pictureView.resized();
+ }
+ },
+ search: function() {
+ this.searchText = this.$.searchInput.getValue();
+ this.page = 0;
+ this.results = [];
+ this.$.searchSpinner.show();
+ this.$.flickrSearch.search(this.searchText);
+ },
+ searchResults: function(inSender, inResults) {
+ this.$.searchSpinner.hide();
+ this.$.moreSpinner.hide();
+ this.results = this.results.concat(inResults);
+ this.$.list.setCount(this.results.length);
+ if (this.page === 0) {
+ this.$.list.reset();
+ } else {
+ this.$.list.refresh();
+ }
+ },
+ setupItem: function(inSender, inEvent) {
+ var i = inEvent.index;
+ var item = this.results[i];
+ this.$.item.addRemoveClass("onyx-selected", inSender.isSelected(inEvent.index));
+ this.$.thumbnail.setSrc(item.thumbnail);
+ this.$.title.setContent(item.title || "Untitled");
+ this.$.more.canGenerate = !this.results[i+1];
+ },
+ more: function() {
+ this.page++;
+ this.$.moreSpinner.show();
+ this.$.flickrSearch.search(this.searchText, this.page);
+ },
+ itemTap: function(inSender, inEvent) {
+ if (enyo.Panels.isScreenNarrow()) {
+ this.setIndex(1);
+ }
+ this.$.imageSpinner.show();
+ var item = this.results[inEvent.index];
+
+ if (item.original == this.$.flickrImage.getSrc()) {
+ this.imageLoaded();
+ } else {
+ this.$.flickrImage.hide();
+ this.$.flickrImage.setSrc(item.original);
+ }
+ },
+ imageLoaded: function() {
+ var img = this.$.flickrImage;
+ img.removeClass("tall");
+ img.removeClass("wide");
+ img.show();
+ var b = img.getBounds();
+ var r = b.height / b.width;
+ if (r >= 1.25) {
+ img.addClass("tall");
+ } else if (r <= 0.8 ) {
+ img.addClass("wide");
+ }
+ this.$.imageSpinner.hide();
+ },
+ showList: function() {
+ this.setIndex(0);
+ }
+});
+
+// A simple component to do a Flickr search.
+enyo.kind({
+ name: "FlickrSearch",
+ kind: "Component",
+ published: {
+ searchText: ""
+ },
+ events: {
+ onResults: ""
+ },
+ url: "http://api.flickr.com/services/rest/",
+ pageSize: 200,
+ api_key: "2a21b46e58d207e4888e1ece0cb149a5",
+ search: function(inSearchText, inPage) {
+ this.searchText = inSearchText || this.searchText;
+ var i = (inPage || 0) * this.pageSize;
+ var params = {
+ method: "flickr.photos.search",
+ format: "json",
+ api_key: this.api_key,
+ per_page: this.pageSize,
+ page: i,
+ text: this.searchText
+ };
+ return new enyo.JsonpRequest({url: this.url, callbackName: "jsoncallback"})
+ .response(this, "processResponse")
+ .go(params)
+ ;
+ },
+ processResponse: function(inSender, inResponse) {
+ var photos = inResponse.photos ? inResponse.photos.photo || [] : [];
+ for (var i=0, p; (p=photos[i]); i++) {
+ var urlprefix = "http://farm" + p.farm + ".static.flickr.com/" + p.server + "/" + p.id + "_" + p.secret;
+ p.thumbnail = urlprefix + "_s.jpg";
+ p.original = urlprefix + ".jpg";
+ }
+ this.doResults(photos);
+ return photos;
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssamplesPanelsSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+.panels-sample-panels {
+ min-height: 320px;
+ min-width: 320px;
+}
+
+.panels-sample-panels > * {
+ border: 2px solid #333;
+ font-size: 5em;
+ text-align: center;
+}
+
+.panels-sample-wide > * {
+ min-width: 50%;
+}
+
+.panels-sample-collapsible > * {
+ min-width: 250px;
+}
+
+.panels-sample-spiral > * {
+ min-width:150px;
+ min-height:150px;
+ max-height:150px;
+ max-width:150px;
+}
+
+.panels-sample-grid > * {
+ min-width:150px;
+ min-height:150px;
+ max-height:150px;
+ max-width:150px;
+}
+.arranger-scroller {
+}
+
+@media screen and (max-width: 480px) {
+ .arranger-scroller {
+ max-height: 270px;
+ }
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssamplesPanelsSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Panels Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/source/wip-package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="PanelsSample.css" rel="stylesheet">
+ <script src="PanelsSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.PanelsSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssamplesPanelsSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,108 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.MyGridArranger",
+ kind: "GridArranger",
+ colHeight: "150",
+ colWidth: "150"
+});
+
+enyo.kind({
+ name: "enyo.sample.PanelsSample",
+ kind: "FittableRows",
+ classes: "enyo-fit",
+ components: [
+ {kind: "FittableColumns", noStretch: true, classes: "onyx-toolbar onyx-toolbar-inline", components: [
+ {kind: "Scroller", thumb: false, fit: true, touch: true, vertical: "hidden", style: "margin: 0;", components: [
+ {classes: "onyx-toolbar-inline", style: "white-space: nowrap;", components: [
+ {kind: "onyx.MenuDecorator", components: [
+ {content:"Arranger"},
+ {name:"arrangerPicker", kind: "onyx.Menu", maxHeight: 360, floating: true, onSelect:"arrangerSelected"}
+ ]},
+ {kind: "onyx.Button", content: "Previous", ontap: "prevPanel"},
+ {kind: "onyx.Button", content: "Next", ontap: "nextPanel"},
+ {kind: "onyx.InputDecorator", style: "width: 60px;", components: [
+ {kind: "onyx.Input", value: 0, onchange: "gotoPanel"}
+ ]},
+ {kind: "onyx.Button", content: "Go", ontap: "gotoPanel"},
+ {kind: "onyx.Button", content: "Add", ontap: "addPanel"},
+ {kind: "onyx.Button", content: "Delete", ontap: "deletePanel"}
+ ]}
+ ]}
+ ]},
+ {kind: "Panels", name:"samplePanels", fit:true, realtimeFit: true, classes: "panels-sample-panels enyo-border-box", components: [
+ {content:0, style:"background:red;"},
+ {content:1, style:"background:orange;"},
+ {content:2, style:"background:yellow;"},
+ {content:3, style:"background:green;"},
+ {content:4, style:"background:blue;"},
+ {content:5, style:"background:indigo;"},
+ {content:6, style:"background:violet;"}
+ ]}
+ ],
+ panelArrangers: [
+ {name: "CardArranger", arrangerKind: "CardArranger"},
+ {name: "CardSlideInArranger", arrangerKind: "CardSlideInArranger"},
+ {name: "CarouselArranger", arrangerKind: "CarouselArranger", classes: "panels-sample-wide"},
+ {name: "CollapsingArranger", arrangerKind: "CollapsingArranger", classes: "panels-sample-collapsible"},
+ {name: "LeftRightArranger", arrangerKind: "LeftRightArranger"},
+ {name: "TopBottomArranger", arrangerKind: "TopBottomArranger", classes: "panels-sample-topbottom"},
+ {name: "SpiralArranger", arrangerKind: "SpiralArranger", classes: "panels-sample-spiral"},
+ {name: "GridArranger", arrangerKind: "enyo.sample.MyGridArranger", classes: "panels-sample-grid"},
+ {name: "DockRightArranger", arrangerKind: "DockRightArranger", classes: "panels-sample-collapsible"}
+ ],
+ bgcolors: ["red", "orange", "yellow", "green", "blue", "indigo", "violet"],
+ create: function() {
+ this.inherited(arguments);
+ for (var i=0; i<this.panelArrangers.length; i++) {
+ this.$.arrangerPicker.createComponent({content:this.panelArrangers[i].name});
+ }
+ this.panelCount=this.$.samplePanels.getPanels().length;
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ },
+ arrangerSelected: function(inSender, inEvent) {
+ var sp = this.$.samplePanels;
+ var p = this.panelArrangers[inEvent.originator.indexInContainer()-1];
+ if (this.currentClass) {
+ sp.removeClass(this.currentClass);
+ }
+ if (p.classes) {
+ sp.addClass(p.classes);
+ this.currentClass = p.classes;
+ }
+ sp.setArrangerKind(p.arrangerKind);
+ if (enyo.Panels.isScreenNarrow()) {
+ this.setIndex(1);
+ }
+ },
+ // panels
+ prevPanel: function() {
+ this.$.samplePanels.previous();
+ this.$.input.setValue(this.$.samplePanels.index);
+ },
+ nextPanel: function() {
+ this.$.samplePanels.next();
+ this.$.input.setValue(this.$.samplePanels.index);
+ },
+ gotoPanel: function() {
+ this.$.samplePanels.setIndex(this.$.input.getValue());
+ },
+ panelCount: 0,
+ addPanel: function() {
+ var sp = this.$.samplePanels;
+ var i = this.panelCount++;
+ var p = sp.createComponent({
+ style:"background:" + this.bgcolors[i % this.bgcolors.length],
+ content:i
+ });
+ p.render();
+ sp.reflow();
+ sp.setIndex(i);
+ },
+ deletePanel: function() {
+ var p = this.$.samplePanels.getActive();
+ if (p) {
+ p.destroy();
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssamplesPanelsSlidingSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSlidingSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSlidingSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSlidingSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+.panels-sample-sliding-panels > * {
+ width: 320px;
+ background-color: #EAEAEA;
+ -moz-box-shadow: -4px 0 4px rgba(0,0,0,0.3);
+ -webkit-box-shadow: -4px 0 4px rgba(0,0,0,0.3);
+ box-shadow: -4px 0 4px rgba(0,0,0,0.3);
+}
+
+.panels-sample-sliding-item {
+ padding: 10px;
+ border-bottom: 1px solid black;
+}
+
+.panels-sample-sliding-content {
+ text-align: left;
+ padding: 10px;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssamplesPanelsSlidingSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSlidingSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSlidingSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSlidingSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Panels Sliding App Example</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/source/wip-package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="PanelsSlidingSample.css" rel="stylesheet">
+ <script src="PanelsSlidingSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.PanelsSlidingSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssamplesPanelsSlidingSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSlidingSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSlidingSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/PanelsSlidingSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.PanelsSlidingSample",
+ kind: "FittableRows",
+ classes: "onyx enyo-fit",
+ components: [
+ {kind: "onyx.Toolbar", components: [
+ {content: "Realtime"},
+ {kind: "onyx.Checkbox", onchange: "checkboxChange"}
+ ]},
+ {kind: "Panels", fit: true, classes: "panels-sample-sliding-panels", arrangerKind: "CollapsingArranger", wrap: false, components: [
+ {name: "left", components: [
+ {kind: "List", classes: "enyo-fit", touch: true, count: 1000, onSetupItem: "setupItem", item: "item1", components: [
+ {name: "item1", classes: "panels-sample-sliding-item"}
+ ]}
+ ]},
+ {name: "middle", components: [
+ {kind: "List", classes: "enyo-fit", touch: true, count: 1000, onSetupItem: "setupItem", item: "item2", components: [
+ {name: "item2", classes: "panels-sample-sliding-item"}
+ ]}
+ ]},
+ {name: "body", fit: true, components: [
+ {kind: "Scroller", classes: "enyo-fit", touch: true, components: [
+ {classes: "panels-sample-sliding-content", content: "Broke, down dumb hospitality firewood chitlins. Has mud tired uncle everlastin' cold, out. Hauled thar, up thar tar heffer quarrel farmer fish water is. Simple gritts dogs soap give kickin'. Ain't shiney water range, preacher java rent thar go. Skinned wirey tin farm, trespassin' it, rodeo. Said roped caught creosote go simple. Buffalo butt, jig fried commencin' cipherin' maw, wash. Round-up barefoot jest bible rottgut sittin' trailer shed jezebel. Crop old over poker drinkin' dirt where tools skinned, city-slickers tools liniment mush tarnation. Truck lyin' snakeoil creosote, old a inbred pudneer, slap dirty cain't. Hairy, smokin', nothin' highway hootch pigs drinkin', barefoot bootleg hoosegow mule. Tax-collectors uncle wuz, maw watchin' had jumpin' got redblooded gimmie truck shootin' askin' hootch. No fat ails fire soap cabin jail, reckon if trespassin' fixin' rustle jest liniment. Ya huntin' catfish shot g
ood bankrupt. Fishin' sherrif has, fat cooked shed old. Broke, down dumb hospitality firewood chitlins. Has mud tired uncle everlastin' cold, out. Hauled thar, up thar tar heffer quarrel farmer fish water is. Simple gritts dogs soap give kickin'. Ain't shiney water range, preacher java rent thar go. Skinned wirey tin farm, trespassin' it, rodeo. Said roped caught creosote go simple. Buffalo butt, jig fried commencin' cipherin' maw, wash. Round-up barefoot jest bible rottgut sittin' trailer shed jezebel. Crop old over poker drinkin' dirt where tools skinned, city-slickers tools liniment mush tarnation. Truck lyin' snakeoil creosote, old a inbred pudneer, slap dirty cain't. Hairy, smokin', nothin' highway hootch pigs drinkin', barefoot bootleg hoosegow mule. Tax-collectors uncle wuz, maw watchin' had jumpin' got redblooded gimmie truck shootin' askin' hootch. No fat ails fire soap cabin jail, reckon if trespassin' fixin' rustle jest liniment. Ya huntin' catfish shot good bankrupt. Fis
hin' sherrif has, fat cooked shed old. Broke, down dumb hospitality firewood chitlins. Has mud tired uncle everlastin' cold, out. Hauled thar, up thar tar heffer quarrel farmer fish water is. Simple gritts dogs soap give kickin'. Ain't shiney water range, preacher java rent thar go. Skinned wirey tin farm, trespassin' it, rodeo. Said roped caught creosote go simple. Buffalo butt, jig fried commencin' cipherin' maw, wash. Round-up barefoot jest bible rottgut sittin' trailer shed jezebel. Crop old over poker drinkin' dirt where tools skinned, city-slickers tools liniment mush tarnation. Truck lyin' snakeoil creosote, old a inbred pudneer, slap dirty cain't. Hairy, smokin', nothin' highway hootch pigs drinkin', barefoot bootleg hoosegow mule. Tax-collectors uncle wuz, maw watchin' had jumpin' got redblooded gimmie truck shootin' askin' hootch. No fat ails fire soap cabin jail, reckon if trespassin' fixin' rustle jest liniment. Ya huntin' catfish shot good bankrupt. Fishin' sherrif has,
fat cooked shed old. Broke, down dumb hospitality firewood chitlins. Has mud tired uncle everlastin' cold, out. Hauled thar, up thar tar heffer quarrel farmer fish water is. Simple gritts dogs soap give kickin'. Ain't shiney water range, preacher java rent thar go. Skinned wirey tin farm, trespassin' it, rodeo. Said roped caught creosote go simple. Buffalo butt, jig fried commencin' cipherin' maw, wash. Round-up barefoot jest bible rottgut sittin' trailer shed jezebel. Crop old over poker drinkin' dirt where tools skinned, city-slickers tools liniment mush tarnation. Truck lyin' snakeoil creosote, old a inbred pudneer, slap dirty cain't. Hairy, smokin', nothin' highway hootch pigs drinkin', barefoot bootleg hoosegow mule. Tax-collectors uncle wuz, maw watchin' had jumpin' got redblooded gimmie truck shootin' askin' hootch. No fat ails fire soap cabin jail, reckon if trespassin' fixin' rustle jest liniment. Ya huntin' catfish shot good bankrupt. Fishin' sherrif has, fat cooked shed
old."}
+ ]}
+ ]}
+ ]}
+ ],
+ setupItem: function(inSender, inEvent) {
+ this.$[inSender.item].setContent("This is row number: " + inEvent.index);
+ },
+ checkboxChange: function(inSender) {
+ this.log();
+ this.$.panels.realtimeFit = inSender.getValue();
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssamplesassetssearchinputsearchpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/search-input-search.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/search-input-search.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/search-input-search.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/search-input-search.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/search-input-search.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutpanelssamplesassetsspinnerlargegif"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/spinner-large.gif</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/spinner-large.gif
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/spinner-large.gif 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/spinner-large.gif 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/spinner-large.gif
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/gif
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutpanelssamplesassetsspinnergif"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/spinner.gif</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/spinner.gif
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/spinner.gif 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/spinner.gif 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/panels/samples/assets/spinner.gif
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/gif
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayoutpanelssamplesmenutesthtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/menutest.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/menutest.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/menutest.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Menu Test</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/package.js" type="text/javascript"></script>
+ <script src="../../../onyx/source/wip-package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="PanelsSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ enyo.kind({
+ name: "Test",
+ kind: "FittableRows",
+ classes: "enyo-fit",
+ components: [
+ {kind: "FittableColumns", noStretch: true, classes: "onyx-toolbar onyx-toolbar-inline", components: [
+ {kind: "Scroller", thumb: false, fit: true, touch: true, vertical: "hidden", style: "margin: 0;", components: [
+ {classes: "onyx-toolbar-inline", style: "white-space: nowrap;", components: [
+ {kind: "onyx.MenuDecorator", components: [
+ {content:"Okay!"},
+ {kind: "onyx.Menu", floating:true, components:[
+ {content:"Foo"},
+ {content:"Bar"},
+ {content:"Boom"},
+ {content:"Boom"},
+ {content:"Pow"}
+ ]}
+ ]},
+ {kind: "onyx.MenuDecorator", components: [
+ {content:"Ut oh!"},
+ {kind: "onyx.Menu", name: "badMenu", floating:true}
+ ]}
+ ]}
+ ]}
+ ]},
+ {fit:true}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.$.badMenu.createComponent({content:"Foo"});
+ this.$.badMenu.createComponent({content:"Bar"});
+ this.$.badMenu.createComponent({content:"Boom"});
+ this.$.badMenu.createComponent({content:"Boom"});
+ this.$.badMenu.createComponent({content:"Pow"});
+ }
+ });
+ new Test().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssamplespackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/samples/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/samples/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/samples/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+enyo.depends(
+ "PanelsSample.css",
+ "PanelsSample.js",
+ "PanelsFlickrSample.css",
+ "PanelsFlickrSample.js",
+ "PanelsSlidingSample.css",
+ "PanelsSlidingSample.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssourcePanelscss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/source/Panels.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/source/Panels.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/source/Panels.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+.enyo-panels {
+}
+
+.enyo-panels-fit-narrow {
+}
+
+@media all and (max-width: 800px) {
+ .enyo-panels-fit-narrow > * {
+ min-width: 100%;
+ max-width: 100%;
+ }
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssourcePanelsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/source/Panels.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/source/Panels.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/source/Panels.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,427 @@
</span><ins>+/**
+The _enyo.Panels_ kind is designed to satisfy a variety of common use cases for
+application layout. Using _enyo.Panels_, controls may be arranged as (among
+other things) a carousel, a set of collapsing panels, a card stack that fades
+between panels, or a grid.
+
+Any Enyo control may be placed inside an _enyo.Panels_, but by convention we
+refer to each of these controls as a "panel." From the set of panels in an
+_enyo.Panels_, one is considered to be active. The active panel is set by index
+using the _setIndex_ method. The actual layout of the panels typically changes
+each time the active panel is set, such that the new active panel has the most
+prominent position.
+
+For more information, see the
+[Panels documentation](https://github.com/enyojs/enyo/wiki/Panels) in the Enyo
+Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.Panels",
+ classes: "enyo-panels",
+ published: {
+ /**
+ The index of the active panel. The layout of panels is controlled by
+ the layoutKind, but as a rule, the active panel is displayed in the
+ most prominent position. For example, in the (default) CardArranger
+ layout, the active panel is shown and the other panels are hidden.
+ */
+ index: 0,
+ //* Controls whether the user can drag between panels.
+ draggable: true,
+ //* Controls whether the panels animate when transitioning; for example,
+ //* when _setIndex_ is called.
+ animate: true,
+ //* Controls whether panels "wrap around" when moving past the end.
+ //* The actual effect depends upon the arranger in use.
+ wrap: false,
+ //* Sets the arranger kind to be used for dynamic layout.
+ arrangerKind: "CardArranger",
+ //* By default, each panel will be sized to fit the Panels' width when
+ //* the screen size is narrow enough (less than 800px). Set to false
+ //* to avoid this behavior.
+ narrowFit: true
+ },
+ events: {
+ /**
+ Fires at the start of a panel transition, when _setIndex_ is called
+ and also during dragging.
+
+ _inEvent.fromIndex_ contains the index of the old panel.
+
+ _inEvent.toIndex_ contains the index of the new panel.
+ */
+ onTransitionStart: "",
+ /**
+ Fires at the end of a panel transition, when _setIndex_ is called
+ and also during dragging.
+
+ _inEvent.fromIndex_ contains the index of the old panel.
+
+ _inEvent.toIndex_ contains the index of the new panel.
+ */
+ onTransitionFinish: ""
+ },
+ //* @protected
+ handlers: {
+ ondragstart: "dragstart",
+ ondrag: "drag",
+ ondragfinish: "dragfinish",
+ onscroll: "domScroll"
+ },
+ tools: [
+ {kind: "Animator", onStep: "step", onEnd: "completed"}
+ ],
+ fraction: 0,
+ create: function() {
+ this.transitionPoints = [];
+ this.inherited(arguments);
+ this.arrangerKindChanged();
+ this.narrowFitChanged();
+ this.indexChanged();
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ enyo.makeBubble(this, "scroll");
+ },
+ domScroll: function(inSender, inEvent) {
+ if (this.hasNode()) {
+ if (this.node.scrollLeft > 0) {
+ // Reset scrollLeft position
+ this.node.scrollLeft = 0;
+ }
+ }
+ },
+ initComponents: function() {
+ this.createChrome(this.tools);
+ this.inherited(arguments);
+ },
+ arrangerKindChanged: function() {
+ this.setLayoutKind(this.arrangerKind);
+ },
+ narrowFitChanged: function() {
+ this.addRemoveClass("enyo-panels-fit-narrow", this.narrowFit);
+ },
+ destroy: function() {
+ // When the entire panels is going away, take note so we don't try and do single-panel
+ // remove logic such as changing the index and reflowing when each panel is destroyed
+ this.destroying = true;
+ this.inherited(arguments);
+ },
+ removeControl: function(inControl) {
+ this.inherited(arguments);
+ if (this.destroying && this.controls.length > 0 && this.isPanel(inControl)) {
+ this.setIndex(Math.max(this.index - 1, 0));
+ this.flow();
+ this.reflow();
+ }
+ },
+ isPanel: function() {
+ // designed to be overridden in kinds derived from Panels that have
+ // non-panel client controls
+ return true;
+ },
+ flow: function() {
+ this.arrangements = [];
+ this.inherited(arguments);
+ },
+ reflow: function() {
+ this.arrangements = [];
+ this.inherited(arguments);
+ this.refresh();
+ },
+ //* @public
+ /**
+ Returns an array of contained panels.
+ Subclasses can override this if they don't want the arranger to layout all of their children
+ */
+ getPanels: function() {
+ var p = this.controlParent || this;
+ return p.children;
+ },
+ //* Returns a reference to the active panel--i.e., the panel at the specified index.
+ getActive: function() {
+ var p$ = this.getPanels();
+ //Constrain the index within the array of panels, needed if wrapping is enabled
+ var index = this.index % p$.length;
+ if (index < 0) {
+ index += p$.length;
+ }
+ return p$[index];
+ },
+ /**
+ Returns a reference to the <a href="#enyo.Animator">enyo.Animator</a>
+ instance used to animate panel transitions. The Panels' animator can be used
+ to set the duration of panel transitions, e.g.:
+
+ this.getAnimator().setDuration(1000);
+ */
+ getAnimator: function() {
+ return this.$.animator;
+ },
+ /**
+ Sets the active panel to the panel specified by the given index.
+ Note that if the _animate_ property is set to true, the active panel
+ will animate into view.
+ */
+ setIndex: function(inIndex) {
+ // override setIndex so that indexChanged is called
+ // whether this.index has actually changed or not
+ this.setPropertyValue("index", inIndex, "indexChanged");
+ },
+ /**
+ Sets the active panel to the panel specified by the given index.
+ Regardless of the value of the _animate_ property, the transition to the
+ next panel will not animate and will be immediate.
+ */
+ setIndexDirect: function(inIndex) {
+ this.setIndex(inIndex);
+ this.completed();
+ },
+ //* Transitions to the previous panel--i.e., the panel whose index value is
+ //* one less than that of the current active panel.
+ previous: function() {
+ this.setIndex(this.index-1);
+ },
+ //* Transitions to the next panel--i.e., the panel whose index value is one
+ //* greater than that of the current active panel.
+ next: function() {
+ this.setIndex(this.index+1);
+ },
+ //* @protected
+ clamp: function(inValue) {
+ var l = this.getPanels().length-1;
+ if (this.wrap) {
+ // FIXME: dragging makes assumptions about direction and from->start indexes.
+ //return inValue < 0 ? l : (inValue > l ? 0 : inValue);
+ return inValue;
+ } else {
+ return Math.max(0, Math.min(inValue, l));
+ }
+ },
+ indexChanged: function(inOld) {
+ this.lastIndex = inOld;
+ this.index = this.clamp(this.index);
+ if (!this.dragging && this.$.animator) {
+ if (this.$.animator.isAnimating()) {
+ this.completed();
+ }
+ this.$.animator.stop();
+ if (this.hasNode()) {
+ if (this.animate) {
+ this.startTransition();
+ this.$.animator.play({
+ startValue: this.fraction
+ });
+ } else {
+ this.refresh();
+ }
+ }
+ }
+ },
+ step: function(inSender) {
+ this.fraction = inSender.value;
+ this.stepTransition();
+ },
+ completed: function() {
+ if (this.$.animator.isAnimating()) {
+ this.$.animator.stop();
+ }
+ this.fraction = 1;
+ this.stepTransition();
+ this.finishTransition();
+ },
+ dragstart: function(inSender, inEvent) {
+ if (this.draggable && this.layout && this.layout.canDragEvent(inEvent)) {
+ inEvent.preventDefault();
+ this.dragstartTransition(inEvent);
+ this.dragging = true;
+ this.$.animator.stop();
+ return true;
+ }
+ },
+ drag: function(inSender, inEvent) {
+ if (this.dragging) {
+ inEvent.preventDefault();
+ this.dragTransition(inEvent);
+ }
+ },
+ dragfinish: function(inSender, inEvent) {
+ if (this.dragging) {
+ this.dragging = false;
+ inEvent.preventTap();
+ this.dragfinishTransition(inEvent);
+ }
+ },
+ dragstartTransition: function(inEvent) {
+ if (!this.$.animator.isAnimating()) {
+ var f = this.fromIndex = this.index;
+ this.toIndex = f - (this.layout ? this.layout.calcDragDirection(inEvent) : 0);
+ } else {
+ this.verifyDragTransition(inEvent);
+ }
+ this.fromIndex = this.clamp(this.fromIndex);
+ this.toIndex = this.clamp(this.toIndex);
+ //this.log(this.fromIndex, this.toIndex);
+ this.fireTransitionStart();
+ if (this.layout) {
+ this.layout.start();
+ }
+ },
+ dragTransition: function(inEvent) {
+ // note: for simplicity we choose to calculate the distance directly between
+ // the first and last transition point.
+ var d = this.layout ? this.layout.calcDrag(inEvent) : 0;
+ var t$ = this.transitionPoints, s = t$[0], f = t$[t$.length-1];
+ var as = this.fetchArrangement(s);
+ var af = this.fetchArrangement(f);
+ var dx = this.layout ? this.layout.drag(d, s, as, f, af) : 0;
+ var dragFail = d && !dx;
+ if (dragFail) {
+ //this.log(dx, s, as, f, af);
+ }
+ this.fraction += dx;
+ var fr = this.fraction;
+ if (fr > 1 || fr < 0 || dragFail) {
+ if (fr > 0 || dragFail) {
+ this.dragfinishTransition(inEvent);
+ }
+ this.dragstartTransition(inEvent);
+ this.fraction = 0;
+ // FIXME: account for lost fraction
+ //this.dragTransition(inEvent);
+ }
+ this.stepTransition();
+ },
+ dragfinishTransition: function(inEvent) {
+ this.verifyDragTransition(inEvent);
+ this.setIndex(this.toIndex);
+ // note: if we're still dragging, then we're at a transition boundary
+ // and should fire the finish event
+ if (this.dragging) {
+ this.fireTransitionFinish();
+ }
+ },
+ verifyDragTransition: function(inEvent) {
+ var d = this.layout ? this.layout.calcDragDirection(inEvent) : 0;
+ var f = Math.min(this.fromIndex, this.toIndex);
+ var t = Math.max(this.fromIndex, this.toIndex);
+ if (d > 0) {
+ var s = f;
+ f = t;
+ t = s;
+ }
+ if (f != this.fromIndex) {
+ this.fraction = 1 - this.fraction;
+ }
+ //this.log("old", this.fromIndex, this.toIndex, "new", f, t);
+ this.fromIndex = f;
+ this.toIndex = t;
+ },
+ refresh: function() {
+ if (this.$.animator && this.$.animator.isAnimating()) {
+ this.$.animator.stop();
+ }
+ this.startTransition();
+ this.fraction = 1;
+ this.stepTransition();
+ this.finishTransition();
+ },
+ startTransition: function() {
+ this.fromIndex = this.fromIndex != null ? this.fromIndex : this.lastIndex || 0;
+ this.toIndex = this.toIndex != null ? this.toIndex : this.index;
+ //this.log(this.id, this.fromIndex, this.toIndex);
+ if (this.layout) {
+ this.layout.start();
+ }
+ this.fireTransitionStart();
+ },
+ finishTransition: function() {
+ if (this.layout) {
+ this.layout.finish();
+ }
+ this.transitionPoints = [];
+ this.fraction = 0;
+ this.fromIndex = this.toIndex = null;
+ this.fireTransitionFinish();
+ },
+ fireTransitionStart: function() {
+ var t = this.startTransitionInfo;
+ if (this.hasNode() && (!t || (t.fromIndex != this.fromIndex || t.toIndex != this.toIndex))) {
+ this.startTransitionInfo = {fromIndex: this.fromIndex, toIndex: this.toIndex};
+ this.doTransitionStart(enyo.clone(this.startTransitionInfo));
+ }
+ },
+ fireTransitionFinish: function() {
+ var t = this.finishTransitionInfo;
+ if (this.hasNode() && (!t || (t.fromIndex != this.lastIndex || t.toIndex != this.index))) {
+ this.finishTransitionInfo = {fromIndex: this.lastIndex, toIndex: this.index};
+ this.doTransitionFinish(enyo.clone(this.finishTransitionInfo));
+ }
+ this.lastIndex=this.index;
+ },
+ // gambit: we interpolate between arrangements as needed.
+ stepTransition: function() {
+ if (this.hasNode()) {
+ // select correct transition points and normalize fraction.
+ var t$ = this.transitionPoints;
+ var r = (this.fraction || 0) * (t$.length-1);
+ var i = Math.floor(r);
+ r = r - i;
+ var s = t$[i], f = t$[i+1];
+ // get arrangements and lerp between them
+ var s0 = this.fetchArrangement(s);
+ var s1 = this.fetchArrangement(f);
+ this.arrangement = s0 && s1 ? enyo.Panels.lerp(s0, s1, r) : (s0 || s1);
+ if (this.arrangement && this.layout) {
+ this.layout.flowArrangement();
+ }
+ }
+ },
+ fetchArrangement: function(inName) {
+ if ((inName != null) && !this.arrangements[inName] && this.layout) {
+ this.layout._arrange(inName);
+ this.arrangements[inName] = this.readArrangement(this.getPanels());
+ }
+ return this.arrangements[inName];
+ },
+ readArrangement: function(inC) {
+ var r = [];
+ for (var i=0, c$=inC, c; (c=c$[i]); i++) {
+ r.push(enyo.clone(c._arranger));
+ }
+ return r;
+ },
+ statics: {
+ //* @public
+ /**
+ Returns true when window width is 800px or less. This value must be
+ the same as the "max-width" media query used for panel sizing in
+ _Panels.css_.
+ */
+ isScreenNarrow: function() {
+ return enyo.dom.getWindowWidth() <= 800;
+ },
+ //* @protected
+ lerp: function(inA0, inA1, inFrac) {
+ var r = [];
+ for (var i=0, k$=enyo.keys(inA0), k; (k=k$[i]); i++) {
+ r.push(this.lerpObject(inA0[k], inA1[k], inFrac));
+ }
+ return r;
+ },
+ lerpObject: function(inNew, inOld, inFrac) {
+ var b = enyo.clone(inNew), n, o;
+ // inOld might be undefined when deleting panels
+ if (inOld) {
+ for (var i in inNew) {
+ n = inNew[i];
+ o = inOld[i];
+ if (n != o) {
+ b[i] = n - (n - o) * inFrac;
+ }
+ }
+ }
+ return b;
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssourcearrangersArrangercss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/Arranger.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/Arranger.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/Arranger.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+.enyo-arranger {
+ position: relative;
+ overflow: hidden;
+}
+
+.enyo-arranger.enyo-fit {
+ position: absolute;
+}
+
+.enyo-arranger > * {
+ position: absolute;
+ left: 0;
+ top: 0;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+.enyo-arranger-fit > * {
+ /* override any width/height set on panels */
+ width: 100% !important;
+ height: 100% !important;
+ min-width: 0 !important;
+ min-height: 0 !important;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssourcearrangersArrangerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/Arranger.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/Arranger.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/Arranger.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,230 @@
</span><ins>+/**
+ _enyo.Arranger_ is an <a href="#enyo.Layout">enyo.Layout</a> that considers
+ one of the controls it lays out as active. The other controls are placed
+ relative to the active control as makes sense for the layout.
+
+ Arranger supports dynamic layouts, meaning it's possible to transition
+ between its layouts via animation. Typically, arrangers should lay out
+ controls using CSS transforms, since these are optimized for animation. To
+ support this, the controls in an Arranger are absolutely positioned, and
+ the Arranger kind has an `accelerated` property, which marks controls for
+ CSS compositing. The default setting of "auto" ensures that this will occur
+ if enabled by the platform.
+
+ For more information, see the documentation on
+ [Arrangers](https://github.com/enyojs/enyo/wiki/Arrangers)
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.Arranger",
+ kind: "Layout",
+ layoutClass: "enyo-arranger",
+ /**
+ Sets controls being laid out to use CSS compositing. A setting of "auto"
+ will mark controls for compositing if the platform supports it.
+ */
+ accelerated: "auto",
+ //* Property of the drag event used to calculate the amount a drag moves the layout
+ dragProp: "ddx",
+ //* Property of the drag event used to calculate the direction of a drag
+ dragDirectionProp: "xDirection",
+ //* Property of the drag event used to calculate whether a drag should occur
+ canDragProp: "horizontal",
+ /**
+ If set to true, transitions between non-adjacent arrangements will go
+ through the intermediate arrangements. This is useful when direct
+ transitions between arrangements would be visually jarring.
+ */
+ incrementalPoints: false,
+ /**
+ Called when removing an arranger (for example, when switching a Panels
+ control to a different arrangerKind). Subclasses should implement this
+ function to reset whatever properties they've changed on child controls.
+ You *must* call the superclass implementation in your subclass's
+ _destroy_ function.
+ */
+ destroy: function() {
+ var c$ = this.container.getPanels();
+ for (var i=0, c; (c=c$[i]); i++) {
+ c._arranger = null;
+ }
+ this.inherited(arguments);
+ },
+ /**
+ Arranges the given array of controls (_inC_) in the layout specified by
+ _inName_. When implementing this method, rather than apply styling
+ directly to controls, call _arrangeControl(inControl, inArrangement)_
+ with an _inArrangement_ object with styling settings. These will then be
+ applied via the _flowControl(inControl, inArrangement)_ method.
+ */
+ arrange: function(inC, inName) {
+ },
+ /**
+ Sizes the controls in the layout. This method is called only at reflow
+ time. Note that sizing is separated from other layout done in the
+ _arrange_ method because it is expensive and not suitable for dynamic
+ layout.
+ */
+ size: function() {
+ },
+ /**
+ Called when a layout transition begins. Implement this method to perform
+ tasks that should only occur when a transition starts; for example, some
+ controls could be shown or hidden. In addition, the _transitionPoints_
+ array may be set on the container to dictate the named arrangments
+ between which the transition occurs.
+ */
+ start: function() {
+ var f = this.container.fromIndex, t = this.container.toIndex;
+ var p$ = this.container.transitionPoints = [f];
+ // optionally add a transition point for each index between from and to.
+ if (this.incrementalPoints) {
+ var d = Math.abs(t - f) - 2;
+ var i = f;
+ while (d >= 0) {
+ i = i + (t < f ? -1 : 1);
+ p$.push(i);
+ d--;
+ }
+ }
+ p$.push(this.container.toIndex);
+ },
+ /**
+ Called when a layout transition completes. Implement this method to
+ perform tasks that should only occur when a transition ends; for
+ example, some controls could be shown or hidden.
+ */
+ finish: function() {
+ },
+ /**
+ Called when dragging the layout, this method returns the difference in
+ pixels between the arrangement _inA0_ for layout setting _inI0_ and
+ arrangement _inA1_ for layout setting _inI1_. This data is used to calculate
+ the percentage that a drag should move the layout between two active states.
+ */
+ calcArrangementDifference: function(inI0, inA0, inI1, inA1) {
+ },
+ //* @protected
+ canDragEvent: function(inEvent) {
+ return inEvent[this.canDragProp];
+ },
+ calcDragDirection: function(inEvent) {
+ return inEvent[this.dragDirectionProp];
+ },
+ calcDrag: function(inEvent) {
+ return inEvent[this.dragProp];
+ },
+ drag: function(inDp, inAn, inA, inBn, inB) {
+ var f = this.measureArrangementDelta(-inDp, inAn, inA, inBn, inB);
+ return f;
+ },
+ measureArrangementDelta: function(inX, inI0, inA0, inI1, inA1) {
+ var d = this.calcArrangementDifference(inI0, inA0, inI1, inA1);
+ var s = d ? inX / Math.abs(d) : 0;
+ s = s * (this.container.fromIndex > this.container.toIndex ? -1 : 1);
+ //enyo.log("delta", s);
+ return s;
+ },
+ _arrange: function(inIndex) {
+ // guard against being called before we've been rendered
+ if (!this.containerBounds) {
+ this.reflow();
+ }
+ var c$ = this.getOrderedControls(inIndex);
+ this.arrange(c$, inIndex);
+ },
+ arrangeControl: function(inControl, inArrangement) {
+ inControl._arranger = enyo.mixin(inControl._arranger || {}, inArrangement);
+ },
+ // called before HTML is generated
+ flow: function() {
+ this.c$ = [].concat(this.container.getPanels());
+ this.controlsIndex = 0;
+ for (var i=0, c$=this.container.getPanels(), c; (c=c$[i]); i++) {
+ enyo.dom.accelerate(c, this.accelerated);
+ if (enyo.platform.safari) {
+ // On Safari-desktop, sometimes having the panel's direct child set to accelerate isn't sufficient
+ // this is most often the case with Lists contained inside another control, inside a Panels
+ var grands=c.children;
+ for (var j=0, kid; (kid=grands[j]); j++) {
+ enyo.dom.accelerate(kid, this.accelerated);
+ }
+ }
+ }
+ },
+ // called during "rendered" phase
+ reflow: function() {
+ var cn = this.container.hasNode();
+ this.containerBounds = cn ? {width: cn.clientWidth, height: cn.clientHeight} : {};
+ this.size();
+ },
+ flowArrangement: function() {
+ var a = this.container.arrangement;
+ if (a) {
+ for (var i=0, c$=this.container.getPanels(), c; (c=c$[i]); i++) {
+ this.flowControl(c, a[i]);
+ }
+ }
+ },
+ //* @public
+ /**
+ Lays out the control (_inControl_) according to the settings stored in
+ the _inArrangment_ object. By default, _flowControl_ will apply settings
+ of left, top, and opacity. This method should only be implemented to
+ apply other settings made via _arrangeControl_.
+ */
+ flowControl: function(inControl, inArrangement) {
+ enyo.Arranger.positionControl(inControl, inArrangement);
+ var o = inArrangement.opacity;
+ if (o != null) {
+ enyo.Arranger.opacifyControl(inControl, o);
+ }
+ },
+ //* @protected
+ // Gets an array of controls arranged in state order.
+ // note: optimization, dial around a single array.
+ getOrderedControls: function(inIndex) {
+ var whole = Math.floor(inIndex);
+ var a = whole - this.controlsIndex;
+ var sign = a > 0;
+ var c$ = this.c$ || [];
+ for (var i=0; i<Math.abs(a); i++) {
+ if (sign) {
+ c$.push(c$.shift());
+ } else {
+ c$.unshift(c$.pop());
+ }
+ }
+ this.controlsIndex = whole;
+ return c$;
+ },
+ statics: {
+ // Positions a control via transform: translateX/Y if supported and falls back to left/top if not.
+ positionControl: function(inControl, inBounds, inUnit) {
+ var unit = inUnit || "px";
+ if (!this.updating) {
+ // IE10 uses setBounds because of control hit caching problems seem in some apps
+ if (enyo.dom.canTransform() && !enyo.platform.android && enyo.platform.ie !== 10) {
+ var l = inBounds.left, t = inBounds.top;
+ l = enyo.isString(l) ? l : l && (l + unit);
+ t = enyo.isString(t) ? t : t && (t + unit);
+ enyo.dom.transform(inControl, {translateX: l || null, translateY: t || null});
+ } else {
+ inControl.setBounds(inBounds, inUnit);
+ }
+ }
+ },
+ opacifyControl: function(inControl, inOpacity) {
+ var o = inOpacity;
+ // FIXME: very high/low settings of opacity can cause a control to
+ // blink so cap this here.
+ o = o > 0.99 ? 1 : (o < 0.01 ? 0 : o);
+ // note: we only care about ie8
+ if (enyo.platform.ie < 9) {
+ inControl.applyStyle("filter", "progid:DXImageTransform.Microsoft.Alpha(Opacity=" + (o * 100) + ")");
+ } else {
+ inControl.applyStyle("opacity", o);
+ }
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssourcearrangersCardArrangerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CardArranger.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CardArranger.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CardArranger.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+/**
+ _enyo.CardArranger_ is an <a href="#enyo.Arranger">enyo.Arranger</a> that
+ displays only one active control. The non-active controls are hidden with
+ _setShowing(false)_. Transitions between arrangements are handled by fading
+ from one control to the next.
+
+ For more information, see the documentation on
+ [Arrangers](https://github.com/enyojs/enyo/wiki/Arrangers) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.CardArranger",
+ kind: "Arranger",
+ //* @protected
+ layoutClass: "enyo-arranger enyo-arranger-fit",
+ calcArrangementDifference: function(inI0, inA0, inI1, inA1) {
+ return this.containerBounds.width;
+ },
+ arrange: function(inC, inName) {
+ for (var i=0, c, b, v; (c=inC[i]); i++) {
+ v = (i === 0) ? 1 : 0;
+ this.arrangeControl(c, {opacity: v});
+ }
+ },
+ start: function() {
+ this.inherited(arguments);
+ var c$ = this.container.getPanels();
+ for (var i=0, c; (c=c$[i]); i++) {
+ var wasShowing=c.showing;
+ c.setShowing(i == this.container.fromIndex || i == (this.container.toIndex));
+ if (c.showing && !wasShowing) {
+ c.resized();
+ }
+ }
+ },
+ finish: function() {
+ this.inherited(arguments);
+ var c$ = this.container.getPanels();
+ for (var i=0, c; (c=c$[i]); i++) {
+ c.setShowing(i == this.container.toIndex);
+ }
+ },
+ destroy: function() {
+ var c$ = this.container.getPanels();
+ for (var i=0, c; (c=c$[i]); i++) {
+ enyo.Arranger.opacifyControl(c, 1);
+ if (!c.showing) {
+ c.setShowing(true);
+ }
+ }
+ this.inherited(arguments);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssourcearrangersCardSlideInArrangerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CardSlideInArranger.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CardSlideInArranger.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CardSlideInArranger.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,67 @@
</span><ins>+/**
+ _enyo.CardSlideInArranger_ is an <a href="#enyo.Arranger">enyo.Arranger</a>
+ that displays only one active control. The non-active controls are hidden
+ with _setShowing(false)_. Transitions between arrangements are handled by
+ sliding the new control over the current one.
+
+ Note that CardSlideInArranger always slides controls in from the right. If
+ you want an arranger that slides to the right and left, try
+ <a href="#enyo.LeftRightArranger">enyo.LeftRightArranger</a>.
+
+ For more information, see the documentation on
+ [Arrangers](https://github.com/enyojs/enyo/wiki/Arrangers) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.CardSlideInArranger",
+ kind: "CardArranger",
+ //* @protected
+ start: function() {
+ var c$ = this.container.getPanels();
+ for (var i=0, c; (c=c$[i]); i++) {
+ var wasShowing=c.showing;
+ c.setShowing(i == this.container.fromIndex || i == (this.container.toIndex));
+ if (c.showing && !wasShowing) {
+ c.resized();
+ }
+ }
+ var l = this.container.fromIndex;
+ i = this.container.toIndex;
+ this.container.transitionPoints = [
+ i + "." + l + ".s",
+ i + "." + l + ".f"
+ ];
+ },
+ finish: function() {
+ this.inherited(arguments);
+ var c$ = this.container.getPanels();
+ for (var i=0, c; (c=c$[i]); i++) {
+ c.setShowing(i == this.container.toIndex);
+ }
+ },
+ arrange: function(inC, inName) {
+ var p = inName.split(".");
+ var f = p[0], s= p[1], starting = (p[2] == "s");
+ var b = this.containerBounds.width;
+ for (var i=0, c$=this.container.getPanels(), c, v; (c=c$[i]); i++) {
+ v = b;
+ if (s == i) {
+ v = starting ? 0 : -b;
+ }
+ if (f == i) {
+ v = starting ? b : 0;
+ }
+ if (s == i && s == f) {
+ v = 0;
+ }
+ this.arrangeControl(c, {left: v});
+ }
+ },
+ destroy: function() {
+ var c$ = this.container.getPanels();
+ for (var i=0, c; (c=c$[i]); i++) {
+ enyo.Arranger.positionControl(c, {left: null});
+ }
+ this.inherited(arguments);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssourcearrangersCarouselArrangerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CarouselArranger.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CarouselArranger.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CarouselArranger.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,117 @@
</span><ins>+/**
+ _enyo.CarouselArranger_ is an <a href="#enyo.Arranger">enyo.Arranger</a>
+ that displays the active control, along with some number of inactive
+ controls to fill the available space. The active control is positioned on
+ the left side of the container, and the rest of the views are laid out to
+ the right.
+
+ One of the controls may have _fit: true_ set, in which case it will take up
+ any remaining space after all of the other controls have been sized.
+
+ For best results with CarouselArranger, you should set a minimum width for
+ each control via a CSS style, e.g., _min-width: 25%_ or _min-width: 250px_.
+
+ Transitions between arrangements are handled by sliding the new controls in
+ from the right and sliding the old controls off to the left.
+
+ For more information, see the documentation on
+ [Arrangers](https://github.com/enyojs/enyo/wiki/Arrangers) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.CarouselArranger",
+ kind: "Arranger",
+ //* @protected
+ size: function() {
+ var c$ = this.container.getPanels();
+ var padding = this.containerPadding = this.container.hasNode() ? enyo.dom.calcPaddingExtents(this.container.node) : {};
+ var pb = this.containerBounds;
+ var i, e, s, m, c;
+ pb.height -= padding.top + padding.bottom;
+ pb.width -= padding.left + padding.right;
+ // used space
+ var fit;
+ for (i=0, s=0; (c=c$[i]); i++) {
+ m = enyo.dom.calcMarginExtents(c.hasNode());
+ c.width = c.getBounds().width;
+ c.marginWidth = m.right + m.left;
+ s += (c.fit ? 0 : c.width) + c.marginWidth;
+ if (c.fit) {
+ fit = c;
+ }
+ }
+ if (fit) {
+ var w = pb.width - s;
+ fit.width = w >= 0 ? w : fit.width;
+ }
+ for (i=0, e=padding.left; (c=c$[i]); i++) {
+ c.setBounds({top: padding.top, bottom: padding.bottom, width: c.fit ? c.width : null});
+ }
+ },
+ arrange: function(inC, inName) {
+ if (this.container.wrap) {
+ this.arrangeWrap(inC, inName);
+ } else {
+ this.arrangeNoWrap(inC, inName);
+ }
+ },
+ arrangeNoWrap: function(inC, inName) {
+ var i, aw, cw, c;
+ var c$ = this.container.getPanels();
+ var s = this.container.clamp(inName);
+ var nw = this.containerBounds.width;
+ // do we have enough content to fill the width?
+ for (i=s, cw=0; (c=c$[i]); i++) {
+ cw += c.width + c.marginWidth;
+ if (cw > nw) {
+ break;
+ }
+ }
+ // if content width is less than needed, adjust starting point index and offset
+ var n = nw - cw;
+ var o = 0;
+ if (n > 0) {
+ var s1 = s;
+ for (i=s-1, aw=0; (c=c$[i]); i--) {
+ aw += c.width + c.marginWidth;
+ if (n - aw <= 0) {
+ o = (n - aw);
+ s = i;
+ break;
+ }
+ }
+ }
+ // arrange starting from needed index with detected offset so we fill space
+ var w, e;
+ for (i=0, e=this.containerPadding.left + o; (c=c$[i]); i++) {
+ w = c.width + c.marginWidth;
+ if (i < s) {
+ this.arrangeControl(c, {left: -w});
+ } else {
+ this.arrangeControl(c, {left: Math.floor(e)});
+ e += w;
+ }
+ }
+ },
+ arrangeWrap: function(inC, inName) {
+ for (var i=0, e=this.containerPadding.left, m, c; (c=inC[i]); i++) {
+ this.arrangeControl(c, {left: e});
+ e += c.width + c.marginWidth;
+ }
+ },
+ calcArrangementDifference: function(inI0, inA0, inI1, inA1) {
+ var i = Math.abs(inI0 % this.c$.length);
+ return inA0[i].left - inA1[i].left;
+ },
+ destroy: function() {
+ var c$ = this.container.getPanels();
+ for (var i=0, c; (c=c$[i]); i++) {
+ enyo.Arranger.positionControl(c, {left: null, top: null});
+ c.applyStyle("top", null);
+ c.applyStyle("bottom", null);
+ c.applyStyle("left", null);
+ c.applyStyle("width", null);
+ }
+ this.inherited(arguments);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssourcearrangersCollapsingArrangerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CollapsingArranger.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CollapsingArranger.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/CollapsingArranger.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,101 @@
</span><ins>+/**
+ _enyo.CollapsingArranger_ is an <a href="#enyo.Arranger">enyo.Arranger</a>
+ that displays the active control, along with some number of inactive
+ controls to fill the available space. The active control is positioned on
+ the left side of the container and the rest of the views are laid out to the
+ right. The last control, if visible, will expand to fill whatever space is
+ not taken up by the previous controls.
+
+ For best results with CollapsingArranger, you should set a minimum width
+ for each control via a CSS style, e.g., _min-width: 25%_ or
+ _min-width: 250px_.
+
+ Transitions between arrangements are handled by sliding the new control in
+ from the right and collapsing the old control to the left.
+
+ For more information, see the documentation on
+ [Arrangers](https://github.com/enyojs/enyo/wiki/Arrangers) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.CollapsingArranger",
+ kind: "CarouselArranger",
+ /**
+ The "peekWidth" property specifies the amount each panel should be
+ offset from the left when it is selected. This allows controls on the
+ underlying panel to the left of the selected one to be partially
+ revealed.
+ */
+ peekWidth: 0,
+ //* @protected
+ size: function() {
+ this.clearLastSize();
+ this.inherited(arguments);
+ },
+ // clear size from last if it's not actually the last
+ // (required for adding another control)
+ clearLastSize: function() {
+ for (var i=0, c$=this.container.getPanels(), c; (c=c$[i]); i++) {
+ if (c._fit && i != c$.length-1) {
+ c.applyStyle("width", null);
+ c._fit = null;
+ }
+ }
+ },
+ constructor: function() {
+ this.inherited(arguments);
+ this.peekWidth = this.container.peekWidth != null ? this.container.peekWidth : this.peekWidth;
+ },
+ arrange: function(inC, inIndex) {
+ var c$ = this.container.getPanels();
+ for (var i=0, e=this.containerPadding.left, m, c, n=0; (c=c$[i]); i++) {
+ if(c.getShowing()){
+ this.arrangeControl(c, {left: e + n * this.peekWidth});
+ if (i >= inIndex) {
+ e += c.width + c.marginWidth - this.peekWidth;
+ }
+ n++;
+ } else {
+ this.arrangeControl(c, {left: e});
+ if (i >= inIndex) {
+ e += c.width + c.marginWidth;
+ }
+ }
+ // FIXME: overdragging-ish
+ if (i == c$.length - 1 && inIndex < 0) {
+ this.arrangeControl(c, {left: e - inIndex});
+ }
+ }
+ },
+ calcArrangementDifference: function(inI0, inA0, inI1, inA1) {
+ var i = this.container.getPanels().length-1;
+ return Math.abs(inA1[i].left - inA0[i].left);
+ },
+ flowControl: function(inControl, inA) {
+ this.inherited(arguments);
+ if (this.container.realtimeFit) {
+ var c$ = this.container.getPanels();
+ var l = c$.length-1;
+ var last = c$[l];
+ if (inControl == last) {
+ this.fitControl(inControl, inA.left);
+ }
+ }
+
+ },
+ finish: function() {
+ this.inherited(arguments);
+ if (!this.container.realtimeFit && this.containerBounds) {
+ var c$ = this.container.getPanels();
+ var a$ = this.container.arrangement;
+ var l = c$.length-1;
+ var c = c$[l];
+ this.fitControl(c, a$[l].left);
+ }
+ },
+ fitControl: function(inControl, inOffset) {
+ inControl._fit = true;
+ inControl.applyStyle("width", (this.containerBounds.width - inOffset) + "px");
+ inControl.resized();
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssourcearrangersDockRightArrangerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/DockRightArranger.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/DockRightArranger.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/DockRightArranger.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,133 @@
</span><ins>+/**
+ _enyo.DockRightArranger_ is an <a href="#enyo.Arranger">enyo.Arranger</a>
+ that displays the active control, along with some number of inactive
+ controls to fill the available space. The active control is positioned on
+ the right side of the container and the rest of the views are laid out to the
+ right.
+
+ For best results with DockRightArranger, you should set a minimum width
+ for each control via a CSS style, e.g., _min-width: 25%_ or
+ _min-width: 250px_.
+
+ Transitions between arrangements are handled by sliding the new control in
+ from the right. If the width of the old control(s) can fit within the container,
+ they will slide to the left. If not, the old control(s) will collapse to the left.
+
+ For more information, see the documentation on
+ [Arrangers](https://github.com/enyojs/enyo/wiki/Arrangers) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.DockRightArranger",
+ kind: "Arranger",
+ //* If true, the base panel (index 0) will fill the width of the container,
+ //* while newer controls will slide in and collapse on top of it
+ basePanel: false,
+ //* How many px should panels overlap
+ overlap: 0,
+ //* Column width
+ layoutWidth: 0,
+ //* @protected
+ constructor: function() {
+ this.inherited(arguments);
+ this.overlap = this.container.overlap != null ? this.container.overlap : this.overlap;
+ this.layoutWidth = this.container.layoutWidth != null ? this.container.layoutWidth : this.layoutWidth;
+ },
+ size: function() {
+ var c$ = this.container.getPanels();
+ var padding = this.containerPadding = this.container.hasNode() ? enyo.dom.calcPaddingExtents(this.container.node) : {};
+ var pb = this.containerBounds;
+ var i, m, c;
+ pb.width -= padding.left + padding.right;
+ var nw = pb.width;
+ var len = c$.length;
+ // panel arrangement positions
+ this.container.transitionPositions = {};
+
+ for (i=0; (c=c$[i]); i++) {
+ c.width = ((i===0) && (this.container.basePanel)) ? nw : c.getBounds().width;
+ }
+
+ for (i=0; (c=c$[i]); i++) {
+
+ if ((i===0) && (this.container.basePanel)) {
+ c.setBounds({width: nw});
+ }
+ c.setBounds({top: padding.top, bottom: padding.bottom});
+
+ for (j=0; (c=c$[j]); j++) {
+ var xPos;
+ // index 0 always should always be left-aligned at 0px
+ if ((i===0) && (this.container.basePanel)) {
+ xPos = 0;
+ // else newer panels should be positioned off the viewport
+ } else if (j < i) {
+ xPos = nw;
+ // else active panel should be right-aligned
+ } else if (i === j) {
+ var offset = nw > this.layoutWidth ? this.overlap : 0;
+ xPos = (nw - c$[i].width) + offset;
+ } else {
+ break;
+ }
+ this.container.transitionPositions[i + "." + j] = xPos;
+ }
+
+ if (j < len) {
+ var leftAlign = false;
+ for (k=i+1; k<len; k++) {
+ var offset = 0;
+ // position panel to left: 0px
+ if (leftAlign) {
+ offset = 0;
+ // else if next panel cannot fit within container
+ } else if ( (c$[i].width + c$[k].width - this.overlap) > nw ) {
+ //} else if ( (c$[i].width + c$[k].width) > nw ) {
+ offset = 0;
+ leftAlign = true;
+ } else {
+ offset = c$[i].width - this.overlap;
+ for (m=i; m<k; m++) {
+ var _w = offset + c$[m+1].width - this.overlap;
+ if (_w < nw) {
+ offset = _w;
+ } else {
+ offset = nw;
+ break;
+ }
+ }
+ offset = nw - offset;
+ }
+ this.container.transitionPositions[i + "." + k] = offset;
+ }
+ }
+
+ }
+ },
+ arrange: function(inC, inName) {
+ var i, c;
+ var c$ = this.container.getPanels();
+ var s = this.container.clamp(inName);
+
+ for (i=0; (c=c$[i]); i++) {
+ var xPos = this.container.transitionPositions[i + "." + s];
+ this.arrangeControl(c, {left: xPos});
+ }
+ },
+ calcArrangementDifference: function(inI0, inA0, inI1, inA1) {
+ var p = this.container.getPanels();
+ var w = (inI0 < inI1) ? p[inI1].width : p[inI0].width;
+ return w;
+ },
+ destroy: function() {
+ var c$ = this.container.getPanels();
+ for (var i=0, c; (c=c$[i]); i++) {
+ enyo.Arranger.positionControl(c, {left: null, top: null});
+ c.applyStyle("top", null);
+ c.applyStyle("bottom", null);
+ c.applyStyle("left", null);
+ c.applyStyle("width", null);
+ }
+ this.inherited(arguments);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssourcearrangersOtherArrangersjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/OtherArrangers.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/OtherArrangers.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/OtherArrangers.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,258 @@
</span><ins>+/**
+ _enyo.LeftRightArranger_ is an <a href="#enyo.Arranger">enyo.Arranger</a>
+ that displays the active control and some of the previous and next controls.
+ The active control is centered horizontally in the container, and the
+ previous and next controls are laid out to the left and right, respectively.
+
+ Transitions between arrangements are handled by sliding the new control
+ in from the right and sliding the active control out to the left.
+
+ For more information, see the documentation on
+ [Arrangers](https://github.com/enyojs/enyo/wiki/Arrangers) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.LeftRightArranger",
+ kind: "Arranger",
+ //* The margin width (i.e., how much of the previous and next controls
+ //* are visible) in pixels
+ margin: 40,
+ //* @protected
+ axisSize: "width",
+ offAxisSize: "height",
+ axisPosition: "left",
+ constructor: function() {
+ this.inherited(arguments);
+ this.margin = this.container.margin != null ? this.container.margin : this.margin;
+ },
+ size: function() {
+ var c$ = this.container.getPanels();
+ var port = this.containerBounds[this.axisSize];
+ var box = port - this.margin -this.margin;
+ for (var i=0, b, c; (c=c$[i]); i++) {
+ b = {};
+ b[this.axisSize] = box;
+ b[this.offAxisSize] = "100%";
+ c.setBounds(b);
+ }
+ },
+ start: function() {
+ this.inherited(arguments);
+
+ var s = this.container.fromIndex;
+ var f = this.container.toIndex;
+ var c$ = this.getOrderedControls(f);
+ var o = Math.floor(c$.length/2);
+
+ for (var i=0, c; (c=c$[i]); i++) {
+ if (s > f){
+ if (i == (c$.length - o)){
+ c.applyStyle("z-index", 0);
+ } else {
+ c.applyStyle("z-index", 1);
+ }
+ } else {
+ if (i == (c$.length-1 - o)){
+ c.applyStyle("z-index", 0);
+ } else {
+ c.applyStyle("z-index", 1);
+ }
+ }
+ }
+ },
+ arrange: function(inC, inIndex) {
+ var i,c,v,b;
+ if (this.container.getPanels().length==1){
+ b = {};
+ b[this.axisPosition] = this.margin;
+ this.arrangeControl(this.container.getPanels()[0], b);
+ return;
+ }
+ var o = Math.floor(this.container.getPanels().length/2);
+ var c$ = this.getOrderedControls(Math.floor(inIndex)-o);
+ var box = this.containerBounds[this.axisSize] - this.margin -this.margin;
+ var e = this.margin - box * o;
+ for (i=0; (c=c$[i]); i++) {
+ b = {};
+ b[this.axisPosition] = e;
+ this.arrangeControl(c, b);
+ e += box;
+ }
+ },
+ calcArrangementDifference: function(inI0, inA0, inI1, inA1) {
+ if (this.container.getPanels().length==1){
+ return 0;
+ }
+
+ var i = Math.abs(inI0 % this.c$.length);
+ //enyo.log(inI0, inI1);
+ return inA0[i][this.axisPosition] - inA1[i][this.axisPosition];
+ },
+ destroy: function() {
+ var c$ = this.container.getPanels();
+ for (var i=0, c; (c=c$[i]); i++) {
+ enyo.Arranger.positionControl(c, {left: null, top: null});
+ enyo.Arranger.opacifyControl(c, 1);
+ c.applyStyle("left", null);
+ c.applyStyle("top", null);
+ c.applyStyle("height", null);
+ c.applyStyle("width", null);
+ }
+ this.inherited(arguments);
+ }
+});
+
+//* @public
+/**
+ _enyo.TopBottomArranger_ is an <a href="#enyo.Arranger">enyo.Arranger</a>
+ that displays the active control and some of the previous and next controls.
+ The active control is centered vertically in the container, and the previous
+ and next controls are laid out above and below, respectively.
+
+ Transitions between arrangements are handled by sliding the new control
+ in from the bottom and sliding the active control out the top.
+
+ For more information, see the documentation on
+ [Arrangers](https://github.com/enyojs/enyo/wiki/Arrangers) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.TopBottomArranger",
+ kind: "LeftRightArranger",
+ //* Property of the drag event used to calculate the amount a drag moves
+ //* the layout
+ dragProp: "ddy",
+ //* Property of the drag event used to calculate the direction of a drag
+ dragDirectionProp: "yDirection",
+ //* Property of the drag event used to calculate whether a drag should occur
+ canDragProp: "vertical",
+ //* @protected
+ axisSize: "height",
+ offAxisSize: "width",
+ axisPosition: "top"
+});
+
+//* @public
+/**
+ _enyo.SpiralArranger_ is an <a href="#enyo.Arranger">enyo.Arranger</a> that
+ arranges controls in a spiral. The active control is positioned on top and
+ the other controls are laid out in a spiral pattern below.
+
+ Transitions between arrangements are handled by rotating the new control
+ up from below and rotating the active control down to the end of the spiral.
+
+ For more information, see the documentation on
+ [Arrangers](https://github.com/enyojs/enyo/wiki/Arrangers) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.SpiralArranger",
+ kind: "Arranger",
+ //* Always go through incremental arrangements when transitioning
+ incrementalPoints: true,
+ //* The amount of space between successive controls
+ inc: 20,
+ //* @protected
+ size: function() {
+ var c$ = this.container.getPanels();
+ var b = this.containerBounds;
+ var w = this.controlWidth = b.width/3;
+ var h = this.controlHeight = b.height/3;
+ for (var i=0, c; (c=c$[i]); i++) {
+ c.setBounds({width: w, height: h});
+ }
+ },
+ arrange: function(inC, inName) {
+ var s = this.inc;
+ for (var i=0, l=inC.length, c; (c=inC[i]); i++) {
+ var x = Math.cos(i/l * 2*Math.PI) * i * s + this.controlWidth;
+ var y = Math.sin(i/l * 2*Math.PI) * i * s + this.controlHeight;
+ this.arrangeControl(c, {left: x, top: y});
+ }
+ },
+ start: function() {
+ this.inherited(arguments);
+ var c$ = this.getOrderedControls(this.container.toIndex);
+ for (var i=0, c; (c=c$[i]); i++) {
+ c.applyStyle("z-index", c$.length - i);
+ }
+ },
+ calcArrangementDifference: function(inI0, inA0, inI1, inA1) {
+ return this.controlWidth;
+ },
+ destroy: function() {
+ var c$ = this.container.getPanels();
+ for (var i=0, c; (c=c$[i]); i++) {
+ c.applyStyle("z-index", null);
+ enyo.Arranger.positionControl(c, {left: null, top: null});
+ c.applyStyle("left", null);
+ c.applyStyle("top", null);
+ c.applyStyle("height", null);
+ c.applyStyle("width", null);
+ }
+ this.inherited(arguments);
+ }
+});
+
+//* @public
+/**
+ _enyo.GridArranger_ is an <a href="#enyo.Arranger">enyo.Arranger</a> that
+ arranges controls in a grid. The active control is positioned at the
+ top-left of the grid and the other controls are laid out from left to right
+ and then from top to bottom.
+
+ Transitions between arrangements are handled by moving the active control to
+ the end of the grid and shifting the other controls to the left, or up to
+ the previous row, to fill the space.
+
+ For more information, see the documentation on
+ [Arrangers](https://github.com/enyojs/enyo/wiki/Arrangers) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "enyo.GridArranger",
+ kind: "Arranger",
+ //* Always go through incremental arrangements when transitioning
+ incrementalPoints: true,
+ //* @public
+ //* Column width
+ colWidth: 100,
+ //* Column height
+ colHeight: 100,
+ //* @protected
+ size: function() {
+ var c$ = this.container.getPanels();
+ var w=this.colWidth, h=this.colHeight;
+ for (var i=0, c; (c=c$[i]); i++) {
+ c.setBounds({width: w, height: h});
+ }
+ },
+ arrange: function(inC, inIndex) {
+ var w=this.colWidth, h=this.colHeight;
+ var cols = Math.max(1, Math.floor(this.containerBounds.width / w));
+ var c;
+ for (var y=0, i=0; i<inC.length; y++) {
+ for (var x=0; (x<cols) && (c=inC[i]); x++, i++) {
+ this.arrangeControl(c, {left: w*x, top: h*y});
+ }
+ }
+ },
+ flowControl: function(inControl, inA) {
+ this.inherited(arguments);
+ enyo.Arranger.opacifyControl(inControl, inA.top % this.colHeight !== 0 ? 0.25 : 1);
+ },
+ calcArrangementDifference: function(inI0, inA0, inI1, inA1) {
+ return this.colWidth;
+ },
+ destroy: function() {
+ var c$ = this.container.getPanels();
+ for (var i=0, c; (c=c$[i]); i++) {
+ enyo.Arranger.positionControl(c, {left: null, top: null});
+ c.applyStyle("left", null);
+ c.applyStyle("top", null);
+ c.applyStyle("height", null);
+ c.applyStyle("width", null);
+ }
+ this.inherited(arguments);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssourcearrangerspackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/source/arrangers/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+enyo.depends(
+ "Arranger.js",
+ "Arranger.css",
+ "CardArranger.js",
+ "CardSlideInArranger.js",
+ "CarouselArranger.js",
+ "CollapsingArranger.js",
+ "DockRightArranger.js",
+ "OtherArrangers.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutpanelssourcepackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/panels/source/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/panels/source/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/panels/source/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+enyo.depends(
+ "arrangers",
+ "Panels.css",
+ "Panels.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutslideablepackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/slideable/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/slideable/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/slideable/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+enyo.depends(
+ "source"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutslideablesamplesSlideableSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/slideable/samples/SlideableSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/slideable/samples/SlideableSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/slideable/samples/SlideableSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+.slideable-sample {
+ position: absolute;
+ background-color: #333;
+ color: #fff;
+}
+
+.slideable-sample.top {
+ height: 200px;
+ height: 40%;
+ border-bottom: solid 1px #f00;
+}
+
+.slideable-sample.right {
+ right: 0;
+ left: auto;
+ width: 200px;
+ width: 40%;
+ border-left: solid 1px #ff0;
+}
+
+.slideable-sample.bottom {
+ top: auto;
+ bottom: 0;
+ height: 200px;
+ height: 40%;
+ border-top: solid 1px #fff;
+}
+
+.slideable-sample.left {
+ width: 200px;
+ width: 40%;
+ border-right: solid 1px #0ff;
+}
+
+.slideableinfo-sample {
+ background-color: #f0f;
+ border: solid 1px #fff;
+ max-width: 150px;
+ text-align: center;
+ vertical-align: middle;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutslideablesamplesSlideableSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/slideable/samples/SlideableSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/slideable/samples/SlideableSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/slideable/samples/SlideableSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Slideable Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="SlideableSample.css" rel="stylesheet">
+ <script src="SlideableSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.SlideableSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutslideablesamplesSlideableSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/slideable/samples/SlideableSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/slideable/samples/SlideableSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/slideable/samples/SlideableSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.SlideableSample",
+ classes: "enyo-unselectable enyo-fit",
+ style: "overflow: hidden; background-color: #000;",
+ components: [
+ {name: "top", kind: "Slideable", axis: "v", unit: "%", min: -90, max: 0, classes: "enyo-fit slideable-sample top", onChange: "updateInfo"},
+ {name: "right", kind: "Slideable", axis: "h", unit: "%", min: 0, max: 90, classes: "enyo-fit slideable-sample right", onChange: "updateInfo"},
+ {name: "bottom", kind: "Slideable", axis: "v", unit: "%", min: 0, max: 90, classes: "enyo-fit slideable-sample bottom", onChange: "updateInfo"},
+ {name: "left", kind: "Slideable", axis: "h", unit: "%", min: -90, max: 0, classes: "enyo-fit slideable-sample left", onChange: "updateInfo"}
+ ],
+ handlers: {
+ ondragstart: "suppressPanelDrag"
+ },
+ create: function() {
+ this.inherited(arguments);
+ var slideables = [];
+
+ for (var c in this.$) {
+ if (this.$[c].kind === "Slideable") {
+ slideables.push(this.$[c]);
+ }
+ }
+ this.populate(slideables);
+ },
+ populate: function(inSlideables) {
+ var slideable;
+ for (var s in inSlideables) {
+ slideable = inSlideables[s];
+ slideable.createComponents([
+ {style: slideable.axis === "h" ? "height: 38%;" : ""}, // cheating here for the horizontal Slideables to make everything nice and (almost) centered vertically
+ {
+ kind: "enyo.sample.SlideableInfo",
+ layoutKind: (slideable.axis === "v") ? enyo.FittableColumnsLayout : enyo.FittableRowsLayout,
+ classes: "enyo-center", // cheating here for the vertical Slideables to make everything nice and centered horizontally (no effect on horizontal Slideables)
+ info: {
+ name: slideable.name,
+ axis: slideable.axis,
+ unit: slideable.unit,
+ min: slideable.min,
+ max: slideable.max,
+ value: slideable.value
+ }
+ }
+ ]);
+ }
+ },
+ updateInfo: function(inSender) {
+ inSender.waterfallDown("onUpdateInfo", {
+ name: inSender.name,
+ axis: inSender.axis,
+ unit: inSender.unit,
+ min: inSender.min,
+ max: inSender.max,
+ value: Math.round(inSender.value)
+ });
+ return true;
+ },
+ // keeps the view panel from moving in Sampler app while dragging the Slideable
+ suppressPanelDrag: function() {
+ return true;
+ }
+});
+
+enyo.kind({
+ name: "enyo.sample.SlideableInfo",
+ kind: enyo.Control,
+ published: {
+ info: null
+ },
+ components: [
+ {kind: enyo.FittableRows, classes: "slideableinfo-sample", components: [
+ {name: "name"},
+ {name: "axis"},
+ {name: "unit"},
+ {name: "min"},
+ {name: "max"},
+ {name: "value"}
+ ]}
+ ],
+ handlers: {
+ onUpdateInfo: "updateInfo"
+ },
+ create: function() {
+ this.inherited(arguments);
+ this.infoChanged();
+ },
+ infoChanged: function() {
+ for (var p in this.info) {
+ if (this.$[p]) {
+ this.$[p].setContent(enyo.cap(p) + ": " + this.info[p]);
+ }
+ }
+ },
+ updateInfo: function(inSender, inEvent) {
+ this.setInfo(inEvent);
+ return true;
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutslideablesamplespackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/slideable/samples/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/slideable/samples/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/slideable/samples/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+enyo.depends(
+ "SlideableSample.css",
+ "SlideableSample.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutslideablesourceSlideablejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/slideable/source/Slideable.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/slideable/source/Slideable.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/slideable/source/Slideable.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,316 @@
</span><ins>+/**
+ _enyo.Slideable_ is a control that can be dragged either horizontally or
+ vertically between a minimum and a maximum value. When released from
+ dragging, a Slideable will animate to its minimum or maximum position,
+ depending on the direction of the drag.
+
+ The _min_ value specifies a position to the left of, or above, the initial
+ position, to which the Slideable may be dragged.
+ The _max_ value specifies a position to the right of, or below, the initial
+ position, to which the Slideable may be dragged.
+ The _value_ property specifies the current position of the Slideable,
+ between the minimum and maximum positions.
+
+ _min_, _max_, and _value_ may be specified in units of "px" or "%".
+
+ The _axis_ property determines whether the Slideable slides left-to-right
+ ("h") or up-and-down ("v").
+
+ The following control is placed 90% off the screen to the right, and slides
+ to its natural position.
+
+ {kind: "enyo.Slideable", value: -90, min: -90, unit: "%",
+ classes: "enyo-fit", style: "width: 300px;",
+ components: [
+ {content: "stuff"}
+ ]
+ }
+*/
+enyo.kind({
+ name: "enyo.Slideable",
+ kind: "Control",
+ published: {
+ //* Direction of sliding; can be "h" or "v"
+ axis: "h",
+ //* Current position of the Slideable (a value between _min_ and _max_)
+ value: 0,
+ //* Unit for _min_, _max_, and _value_; can be "px" or "%"
+ unit: "px",
+ //* A minimum value to slide to
+ min: 0,
+ //* A maximum value to slide to
+ max: 0,
+ //* When truthy, apply CSS styles to allow GPU compositing of slideable content
+ //* if the platform allows.
+ accelerated: "auto",
+ //* Set to false to prevent the Slideable from dragging with elasticity
+ //* past its _min_ or _max_ value
+ overMoving: true,
+ //* Set to false to disable dragging
+ draggable: true
+ },
+ events: {
+ //* Fires when the Slideable finishes animating.
+ onAnimateFinish: "",
+ //* Fires when the position (i.e., _value_) of the Slideable changes.
+ onChange: ""
+ },
+ //* Set to true to prevent a drag from bubbling beyond the Slideable
+ preventDragPropagation: false,
+ //* @protected
+ tools: [
+ {kind: "Animator", onStep: "animatorStep", onEnd: "animatorComplete"}
+ ],
+ handlers: {
+ ondragstart: "dragstart",
+ ondrag: "drag",
+ ondragfinish: "dragfinish"
+ },
+ kDragScalar: 1,
+ dragEventProp: "dx",
+ unitModifier: false,
+ canTransform: false,
+ //* @protected
+ create: function() {
+ this.inherited(arguments);
+ this.acceleratedChanged();
+ this.transformChanged();
+ this.axisChanged();
+ this.valueChanged();
+ this.addClass("enyo-slideable");
+ },
+ initComponents: function() {
+ this.createComponents(this.tools);
+ this.inherited(arguments);
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ this.canModifyUnit();
+ this.updateDragScalar();
+ },
+ resizeHandler: function() {
+ this.inherited(arguments);
+ this.updateDragScalar();
+ },
+ canModifyUnit: function() {
+ if (!this.canTransform) {
+ var b = this.getInitialStyleValue(this.hasNode(), this.boundary);
+ // If inline style of "px" exists, while unit is "%"
+ if (b.match(/px/i) && (this.unit === "%")) {
+ // Set unitModifier - used to over-ride "%"
+ this.unitModifier = this.getBounds()[this.dimension];
+ }
+ }
+ },
+ getInitialStyleValue: function(inNode, inBoundary) {
+ var s = enyo.dom.getComputedStyle(inNode);
+ if (s) {
+ return s.getPropertyValue(inBoundary);
+ } else if (inNode && inNode.currentStyle) {
+ return inNode.currentStyle[inBoundary];
+ }
+ return "0";
+ },
+ updateBounds: function(inValue, inDimensions) {
+ var inBounds = {};
+ inBounds[this.boundary] = inValue;
+ this.setBounds(inBounds, this.unit);
+
+ this.setInlineStyles(inValue, inDimensions);
+ },
+ updateDragScalar: function() {
+ if (this.unit == "%") {
+ var d = this.getBounds()[this.dimension];
+ this.kDragScalar = d ? 100 / d : 1;
+
+ if (!this.canTransform) {
+ this.updateBounds(this.value, 100);
+ }
+ }
+ },
+ transformChanged: function() {
+ this.canTransform = enyo.dom.canTransform();
+ },
+ acceleratedChanged: function() {
+ if (!(enyo.platform.android > 2)) {
+ enyo.dom.accelerate(this, this.accelerated);
+ }
+ },
+ axisChanged: function() {
+ var h = this.axis == "h";
+ this.dragMoveProp = h ? "dx" : "dy";
+ this.shouldDragProp = h ? "horizontal" : "vertical";
+ this.transform = h ? "translateX" : "translateY";
+ this.dimension = h ? "width" : "height";
+ this.boundary = h ? "left" : "top";
+ },
+ setInlineStyles: function(inValue, inDimensions) {
+ var inBounds = {};
+
+ if (this.unitModifier) {
+ inBounds[this.boundary] = this.percentToPixels(inValue, this.unitModifier);
+ inBounds[this.dimension] = this.unitModifier;
+ this.setBounds(inBounds);
+ } else {
+ if (inDimensions) {
+ inBounds[this.dimension] = inDimensions;
+ } else {
+ inBounds[this.boundary] = inValue;
+ }
+ this.setBounds(inBounds, this.unit);
+ }
+ },
+ valueChanged: function(inLast) {
+ var v = this.value;
+ if (this.isOob(v) && !this.isAnimating()) {
+ this.value = this.overMoving ? this.dampValue(v) : this.clampValue(v);
+ }
+ // FIXME: android cannot handle nested compositing well so apply acceleration only if needed
+ // desktop chrome doesn't like this code path so avoid...
+ if (enyo.platform.android > 2) {
+ if (this.value) {
+ if (inLast === 0 || inLast === undefined) {
+ enyo.dom.accelerate(this, this.accelerated);
+ }
+ } else {
+ enyo.dom.accelerate(this, false);
+ }
+ }
+
+ // If platform supports transforms
+ if (this.canTransform) {
+ enyo.dom.transformValue(this, this.transform, this.value + this.unit);
+ // else update inline styles
+ } else {
+ this.setInlineStyles(this.value, false);
+ }
+ this.doChange();
+ },
+ getAnimator: function() {
+ return this.$.animator;
+ },
+ isAtMin: function() {
+ return this.value <= this.calcMin();
+ },
+ isAtMax: function() {
+ return this.value >= this.calcMax();
+ },
+ calcMin: function() {
+ return this.min;
+ },
+ calcMax: function() {
+ return this.max;
+ },
+ clampValue: function(inValue) {
+ var min = this.calcMin();
+ var max = this.calcMax();
+ return Math.max(min, Math.min(inValue, max));
+ },
+ dampValue: function(inValue) {
+ return this.dampBound(this.dampBound(inValue, this.min, 1), this.max, -1);
+ },
+ dampBound: function(inValue, inBoundary, inSign) {
+ var v = inValue;
+ if (v * inSign < inBoundary * inSign) {
+ v = inBoundary + (v - inBoundary) / 4;
+ }
+ return v;
+ },
+ percentToPixels: function(value, dimension) {
+ return Math.floor((dimension / 100) * value);
+ },
+ pixelsToPercent: function(value) {
+ var boundary = this.unitModifier ? this.getBounds()[this.dimension] : this.container.getBounds()[this.dimension];
+ return (value / boundary) * 100;
+ },
+ // dragging
+ shouldDrag: function(inEvent) {
+ return this.draggable && inEvent[this.shouldDragProp];
+ },
+ isOob: function(inValue) {
+ return inValue > this.calcMax() || inValue < this.calcMin();
+ },
+ dragstart: function(inSender, inEvent) {
+ if (this.shouldDrag(inEvent)) {
+ inEvent.preventDefault();
+ this.$.animator.stop();
+ inEvent.dragInfo = {};
+ this.dragging = true;
+ this.drag0 = this.value;
+ this.dragd0 = 0;
+ return this.preventDragPropagation;
+ }
+ },
+ drag: function(inSender, inEvent) {
+ if (this.dragging) {
+ inEvent.preventDefault();
+ var d = this.canTransform ? inEvent[this.dragMoveProp] * this.kDragScalar : this.pixelsToPercent(inEvent[this.dragMoveProp]);
+ var v = this.drag0 + d;
+ var dd = d - this.dragd0;
+ this.dragd0 = d;
+ if (dd) {
+ inEvent.dragInfo.minimizing = dd < 0;
+ }
+ this.setValue(v);
+ return this.preventDragPropagation;
+ }
+ },
+ dragfinish: function(inSender, inEvent) {
+ if (this.dragging) {
+ this.dragging = false;
+ this.completeDrag(inEvent);
+ inEvent.preventTap();
+ return this.preventDragPropagation;
+ }
+ },
+ completeDrag: function(inEvent) {
+ if (this.value !== this.calcMax() && this.value != this.calcMin()) {
+ this.animateToMinMax(inEvent.dragInfo.minimizing);
+ }
+ },
+ // animation
+ isAnimating: function() {
+ return this.$.animator.isAnimating();
+ },
+ play: function(inStart, inEnd) {
+ this.$.animator.play({
+ startValue: inStart,
+ endValue: inEnd,
+ node: this.hasNode()
+ });
+ },
+ //* @public
+ //* Animates to the given value.
+ animateTo: function(inValue) {
+ this.play(this.value, inValue);
+ },
+ //* Animates to the minimum value.
+ animateToMin: function() {
+ this.animateTo(this.calcMin());
+ },
+ //* Animates to the maximum value.
+ animateToMax: function() {
+ this.animateTo(this.calcMax());
+ },
+ //* @protected
+ animateToMinMax: function(inMin) {
+ if (inMin) {
+ this.animateToMin();
+ } else {
+ this.animateToMax();
+ }
+ },
+ animatorStep: function(inSender) {
+ this.setValue(inSender.value);
+ return true;
+ },
+ animatorComplete: function(inSender) {
+ this.doAnimateFinish(inSender);
+ return true;
+ },
+ //* @public
+ //* Toggles between _min_ and _max_ values with animation.
+ toggleMinMax: function() {
+ this.animateToMinMax(!this.isAtMin());
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayoutslideablesourcepackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/slideable/source/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/slideable/source/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/slideable/source/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+enyo.depends(
+ "Slideable.js"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayouttreepackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/tree/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/tree/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/tree/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+enyo.depends(
+ "source"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayouttreesamplesTreeSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/tree/samples/TreeSample.css ( => )</h4>
<pre class="diff"><span>
<span class="info">Added: 2013/sayaksarkar/trunk/lib/layout/tree/samples/TreeSample.html
===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/tree/samples/TreeSample.html (rev 0)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/tree/samples/TreeSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Tree Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../../layout/package.js" type="text/javascript"></script>
+ <script src="../package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="TreeSample.css" rel="stylesheet">
+ <script src="TreeSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new enyo.sample.TreeSample().renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayouttreesamplesTreeSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/tree/samples/TreeSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/tree/samples/TreeSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/tree/samples/TreeSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+enyo.kind({
+ name: "enyo.sample.TreeSample",
+ classes: "enyo-unselectable enyo-fit",
+ kind: "FittableRows",
+ fit: true,
+ components: [
+ {kind: "Selection", onSelect: "select", onDeselect: "deselect"},
+ {kind: "Scroller", fit: true, components: [
+ {kind: "Node", icon: "assets/folder-open.png", content: "Tree", expandable: true, expanded: true, onExpand: "nodeExpand", onNodeTap: "nodeTap", components: [
+ {icon: "assets/file.png", content: "Alpha"},
+ {icon: "assets/folder-open.png", content: "Bravo", expandable: true, expanded: true, components: [
+ {icon: "assets/file.png", content: "Bravo-Alpha"},
+ {icon: "assets/file.png", content: "Bravo-Bravo"},
+ {icon: "assets/file.png", content: "Bravo-Charlie"}
+ ]},
+ {icon: "assets/folder.png", content: "Charlie", expandable: true, components: [
+ {icon: "assets/file.png", content: "Charlie-Alpha"},
+ {icon: "assets/file.png", content: "Charlie-Bravo"},
+ {icon: "assets/file.png", content: "Charlie-Charlie"}
+ ]},
+ {icon: "assets/folder-open.png", content: "Delta", expandable: true, expanded: true, components: [
+ {icon: "assets/file.png", content: "Delta-Alpha"},
+ {icon: "assets/file.png", content: "Delta-Bravo"},
+ {icon: "assets/file.png", content: "Delta-Charlie"}
+ ]},
+ {icon: "assets/file.png", content: "Epsilon"}
+ ]}
+ ]}
+ ],
+ nodeExpand: function(inSender, inEvent) {
+ inSender.setIcon("assets/" + (inSender.expanded ? "folder-open.png" : "folder.png"));
+ },
+ nodeTap: function(inSender, inEvent) {
+ var node = inEvent.originator;
+ this.$.selection.select(node.id, node);
+ },
+ select: function(inSender, inEvent) {
+ inEvent.data.$.caption.applyStyle("background-color", "lightblue");
+ },
+ deselect: function(inSender, inEvent) {
+ inEvent.data.$.caption.applyStyle("background-color", null);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayouttreesamplesassetsfilepng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/file.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/file.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/file.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/file.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/file.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayouttreesamplesassetsfolderopenpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/folder-open.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/folder-open.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/folder-open.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/folder-open.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/folder-open.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayouttreesamplesassetsfolderpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/folder.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/folder.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/folder.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/folder.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/layout/tree/samples/assets/folder.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunkliblayouttreesamplespackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/tree/samples/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/tree/samples/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/tree/samples/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+enyo.depends(
+ "TreeSample.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayouttreesourceNodecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/tree/source/Node.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/tree/source/Node.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/tree/source/Node.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+.enyo-node {
+ cursor: default;
+ padding: 4px;
+}
+
+.enyo-node img {
+ vertical-align: middle;
+ padding-right: 6px;
+}
+
+.enyo-node-box {
+ overflow: hidden;
+}
+
+.enyo-node-client {
+ position: relative;
+}
+
+.enyo-animate .enyo-node-box, .enyo-animate .enyo-node-client {
+ -ms-transition-property: height, top;
+ -ms-transition-duration: 0.2s, 0.2s;
+ -moz-transition-property: height, top;
+ -moz-transition-duration: 0.2s, 0.2s;
+ -o-transition-property: height, top;
+ -o-transition-duration: 0.2s, 0.2s;
+ -webkit-transition-property: height, top;
+ -webkit-transition-duration: 0.2s, 0.2s;
+ transition-property: height, top;
+ transition-duration: 0.2s, 0.2s;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkliblayouttreesourceNodejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/tree/source/Node.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/tree/source/Node.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/tree/source/Node.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,269 @@
</span><ins>+/**
+ _enyo.Node_ is a control that creates structured trees based on Enyo's child
+ component hierarchy format, e.g.:
+
+ {kind: "Node", icon: "images/folder-open.png", content: "Tree",
+ expandable: true, expanded: true, components: [
+ {icon: "images/file.png", content: "Alpha"},
+ {icon: "images/folder-open.png", content: "Bravo",
+ expandable: true, expanded: false, components: [
+ {icon: "images/file.png", content: "Bravo-Alpha"},
+ {icon: "images/file.png", content: "Bravo-Bravo"},
+ {icon: "images/file.png", content: "Bravo-Charlie"}
+ ]
+ }
+ ]
+ }
+
+ The default kind of components within a node is itself _enyo.Node_, so only
+ the top-level node of the tree needs to be explicitly defined as such.
+
+ When an expandable tree node expands, an _onExpand_ event is sent; when it
+ is tapped, a _nodeTap_ event is sent.
+
+ When the optional property _onlyIconExpands_ is set to true, expandable
+ nodes may only be opened by tapping the icon; tapping the content label
+ will fire the _nodeTap_ event, but will not expand the node.
+*/
+
+enyo.kind({
+ name: "enyo.Node",
+ published: {
+ //* @public
+ //* Whether or not the Node is expandable and has child branches
+ expandable: false,
+ //* Open/closed state of the current Node
+ expanded: false,
+ //* Path to image to be used as the icon for this Node
+ icon: "",
+ /**
+ Optional flag that, when true, causes the Node to expand only when
+ the icon is tapped; not when the contents are tapped
+ */
+ onlyIconExpands: false,
+ //* @protected
+ //* Adds or removes the Enyo-selected CSS class.
+ selected: false
+ },
+ style: "padding: 0 0 0 16px;",
+ content: "Node",
+ defaultKind: "Node",
+ classes: "enyo-node",
+ components: [
+ {name: "icon", kind: "Image", showing: false},
+ {kind: "Control", name: "caption", Xtag: "span", style: "display: inline-block; padding: 4px;", allowHtml: true},
+ {kind: "Control", name: "extra", tag: 'span', allowHtml: true}
+ ],
+ childClient: [
+ {kind: "Control", name: "box", classes: "enyo-node-box", Xstyle: "border: 1px solid orange;", components: [
+ {kind: "Control", name: "client", classes: "enyo-node-client", Xstyle: "border: 1px solid lightblue;"}
+ ]}
+ ],
+ handlers: {
+ ondblclick: "dblclick"
+ },
+ events: {
+ //* @public
+ //* Fired when the Node is tapped
+ onNodeTap: "nodeTap",
+ //* Fired when the Node is double-clicked
+ onNodeDblClick: "nodeDblClick",
+ /**
+ Fired when the Node expands or contracts, as indicated by the
+ 'expanded' property in the event data
+ */
+ onExpand: "nodeExpand",
+ //* Fired when the Node is destroyed
+ onDestroyed: "nodeDestroyed"
+ },
+ //
+ //* @protected
+ create: function() {
+ this.inherited(arguments);
+ //this.expandedChanged();
+ //this.levelChanged();
+ this.selectedChanged();
+ this.iconChanged();
+ },
+ destroy: function() {
+ this.doDestroyed();
+ this.inherited(arguments);
+ },
+ initComponents: function() {
+ // TODO: optimize to create the childClient on demand
+ //this.hasChildren = this.components;
+ if (this.expandable) {
+ this.kindComponents = this.kindComponents.concat(this.childClient);
+ }
+ this.inherited(arguments);
+ },
+ //
+ contentChanged: function() {
+ //this.$.caption.setContent((this.expandable ? (this.expanded ? "-" : "+") : "") + this.content);
+ this.$.caption.setContent(this.content);
+ },
+ iconChanged: function() {
+ this.$.icon.setSrc(this.icon);
+ this.$.icon.setShowing(Boolean(this.icon));
+ },
+ selectedChanged: function() {
+ this.addRemoveClass("enyo-selected", this.selected);
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ if (this.expandable && !this.expanded) {
+ this.quickCollapse();
+ }
+ },
+ //
+ addNodes: function(inNodes) {
+ this.destroyClientControls();
+ for (var i=0, n; n=inNodes[i]; i++) {
+ this.createComponent(n);
+ }
+ this.$.client.render();
+ },
+ addTextNodes: function(inNodes) {
+ this.destroyClientControls();
+ for (var i=0, n; n=inNodes[i]; i++) {
+ this.createComponent({content: n});
+ }
+ this.$.client.render();
+ },
+ //
+ tap: function(inSender, inEvent) {
+ if(!this.onlyIconExpands) {
+ this.toggleExpanded();
+ this.doNodeTap();
+ } else {
+ if((inEvent.target==this.$.icon.hasNode())) {
+ this.toggleExpanded();
+ } else {
+ this.doNodeTap();
+ }
+ }
+ return true;
+ },
+ dblclick: function(inSender, inEvent) {
+ this.doNodeDblClick();
+ return true;
+ },
+ //
+ toggleExpanded: function() {
+ this.setExpanded(!this.expanded);
+ },
+ quickCollapse: function() {
+ this.removeClass("enyo-animate");
+ this.$.box.applyStyle("height", "0");
+ var h = this.$.client.getBounds().height;
+ this.$.client.setBounds({top: -h});
+ },
+ _expand: function() {
+ this.addClass("enyo-animate");
+ var h = this.$.client.getBounds().height;
+ this.$.box.setBounds({height: h});
+ this.$.client.setBounds({top: 0});
+ setTimeout(enyo.bind(this, function() {
+ // things may have happened in the interim, make sure
+ // we only fix height if we are still expanded
+ if (this.expanded) {
+ this.removeClass("enyo-animate");
+ this.$.box.applyStyle("height", "auto");
+ }
+ }), 225);
+ },
+ _collapse: function() {
+ // disable transitions
+ this.removeClass("enyo-animate");
+ // fix the height of our box (rather than 'auto'), this
+ // gives webkit something to lerp from
+ var h = this.$.client.getBounds().height;
+ this.$.box.setBounds({height: h});
+ // yield the thead so DOM can make those changes (without transitions)
+ setTimeout(enyo.bind(this, function() {
+ // enable transitions
+ this.addClass("enyo-animate");
+ // shrink our box to 0
+ this.$.box.applyStyle("height", "0");
+ // slide the contents up
+ this.$.client.setBounds({top: -h});
+ }), 25);
+ },
+ expandedChanged: function(inOldExpanded) {
+ if (!this.expandable) {
+ this.expanded = false;
+ } else {
+ var event = {expanded: this.expanded};
+ this.doExpand(event);
+ if (!event.wait) {
+ this.effectExpanded();
+ }
+ }
+ },
+ effectExpanded: function() {
+ if (this.$.client) {
+ if (!this.expanded) {
+ this._collapse();
+ } else {
+ this._expand();
+ }
+ }
+ //this.contentChanged();
+ }/*,
+ //
+ //
+ levelChanged: function() {
+ this.applyStyle("padding-left", 16 + "px");
+ },
+ toggleChildren: function() {
+ if (this.$.list) {
+ this.$.list.setShowing(this.expanded);
+ }
+ },
+ renderNodes: function(inNodes) {
+ var list = this.createComponent({name: "list", container: this});
+ for (var i=0, n; n=inNodes[i]; i++) {
+ n.setLevel(this.level + 1);
+ n.setContainer(list);
+ n.render();
+ }
+ list.render();
+ },
+ //* @public
+ addNodes: function(inNodes) {
+ this.renderNodes(inNodes);
+ this.toggleChildren();
+ },
+ removeNodes: function() {
+ if (this.$.list) {
+ this.$.list.destroy();
+ }
+ },
+ hasVisibleChildren: function() {
+ return this.expanded && this.$.list && this.$.list.controls.length > 0;
+ },
+ fetchParent: function() {
+ return this.level > 0 && this.container.container;
+ },
+ fetchChildren: function() {
+ return this.$.list && this.$.list.controls;
+ },
+ fetchFirstChild: function() {
+ return this.$.list && this.$.list.controls[0];
+ },
+ fetchLastChild: function() {
+ return this.$.list && this.$.list.controls[this.$.list.controls.length-1];
+ },
+ fetchPrevSibling: function() {
+ var i = this.container.controls.indexOf(this);
+ return this.level > 0 && this.container.controls[i-1];
+ },
+ fetchNextSibling: function() {
+ var i = this.container.controls.indexOf(this);
+ return this.level > 0 && this.container.controls[i+1];
+ },
+ getVisibleBounds: function() {
+ return this.$.client.getBounds();
+ }
+ */
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkliblayouttreesourcepackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/layout/tree/source/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/layout/tree/source/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/layout/tree/source/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+enyo.depends(
+ "Node.css",
+ "Node.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxCONTRIBUTINGmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/CONTRIBUTING md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/CONTRIBUTING md (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/CONTRIBUTING md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+# Contributions
+
+Contributions are welcome for Enyo and its associated libraries including onyx and layout.
+
+Please see [Contributing to Enyo](http://enyojs.com/community/contribute/) for details
+on our contribution policy and guidelines for use of the Enyo-DCO-1.0-Signed-off-by
+line in your commits and pull requests.
+
+If you're interested in introducing new kinds, you might also consider hosting your own repo
+and contributing to the [Enyo community gallery](http://enyojs.com/gallery).
+
+## Modifications to CSS
+
+Onyx CSS is defined using parameterized LESS files. Whenever you make changes to LESS files in Onyx, you'll also need to re-generate and check-in the top-level .css file as well, to maintain backward-compatibility for environments that don't wish to use LESS.
+
+You can re-generate the top-level onyx.css file as follows:
+
+ cd lib/onyx/css
+ ../../../enyo/tools/lessc.sh ./package.js
+
+NOTE: Since LESS generates relative URLs, it's important to run the `lessc.sh` script from the onyx css folder.
+
+Also note you only need to generate the .css file when you're ready to check in your changes. During development, you can do all your testing modifying just LESS files if you include "less-xyz.min.js" in your app's debug.html file, which compiles the LESS client-side during loading:
+
+ <script src="enyo/tools/minifier/node_modules/less/dist/less-1.3.0e.min.js"></script>
+
+Additionally, any new controls contributed should follow this basic pattern to ensure proper themability support:
+
+* Place control's .js file(s) in `lib/onyx/source` and add to `lib/onyx/source/package.js`
+* Place control's .less file(s) in `lib/onyx/css`
+* @import .less file(s) into [`lib/onyx/css/onyx-rules.less`](https://github.com/enyojs/onyx/blob/master/css/onyx-rules.less)
+* Use existing variables from [`lib/onyx/css/onyx-variables.less`](https://github.com/enyojs/onyx/blob/master/css/onyx-variables.less) in your control's LESS files when available, add any new variables your particular control needs along with their default definitions to onyx-variables.less.
+
+Refer to the [UI Theming Guide](https://github.com/enyojs/enyo/wiki/UI-Theming) for more details.
+
+## Samples
+
+Every new control should be accompanied by at least one sample in the [Enyo 2 Sampler](http://enyojs.com/sampler). Read the [Sampler readme](https://github.com/enyojs/sampler) for details on how to go about adding new samples to the Sampler.
+
+Guidelines for samples:
+
+* Samples should live in a folder named `samples`, as a peer to the source
+* Be sure to exercise useful API's and events of the control in the sample
+* When one or more significantly different or interesting configurations of the control are available, include more than one instance in the sample to exhibit use of the different API's
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxLICENSE20txt"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/LICENSE-2.0.txt (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/LICENSE-2.0.txt (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/LICENSE-2.0.txt 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,202 @@
</span><ins>+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxREADMEmd"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/README.md (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/README.md (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/README.md 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+### Looking for the issue tracker?
+It's moved to [https://enyojs.atlassian.net](https://enyojs.atlassian.net).
+
+---
+
+## Onyx UI Library
+
+Onyx is a UI library for Enyo 2.
+
+We originally set out to adapt the Enyo 1 widgets for use with Enyo 2, but we quickly determined that we could achieve better cross-platform compatibility and build a more solid foundation for the future by starting with a clean slate. The result is a new UI library for Enyo 2 called **Onyx**.
+
+Despite the changes under the hood, you'll find that Onyx is clearly an evolution of the Enyo 1 UI from a design point of view. This first Onyx release features a variety of commonly used widgets, including toolbars, text inputs, checkboxes, groups and multiple types of buttons. Onyx also includes a base `Slideable` control that you can use to implement views that slide back and forth between pre-defined positions, including on and off screen.
+
+To get a feel for Onyx, check out the [OnyxSampler example](http://enyojs.com/samples/onyxsampler). Needless to say, we're not done -- we'll be expanding the Onyx widget set as we go.
+
+## Changes
+
+Any time you commit a change to a `.less` file, you also need to
+re-generate the top-level library `.css` file as follows:
+
+ cd lib/onyx/css
+ ../../enyo/tools/lessc.sh ./package.js
+
+This command will generate a new `onyx.css`, which you should check in
+with your `.less` changes.
+
+Please don't manually edit the top-level `onyx.css`: those should be
+treated as output files, and we should only be making changes to
+`.less` files and generating the `.css` file using the above command.
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssButtonless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Button.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Button.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Button.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+/* Button.css */
+.onyx-button {
+ outline: 0;
+ /**/
+ color: @onyx-button-text-color;
+ font-size: @onyx-button-font-size;
+ text-align: center;
+ white-space: nowrap;
+ /**/
+ margin: 0;
+ padding: @onyx-button-padding-tb @onyx-button-padding-lr;
+ overflow: hidden;
+ /**/
+ border-radius: @onyx-button-border-radius;
+ /* for IE8 */
+ border: 1px solid (@onyx-button-background * 0.498);
+ border: 1px solid fade((@onyx-button-background * 0.067), 20%);
+ /*
+ The border and the gradient interact in a strange way that
+ causes the bottom-border (top if the gradient is aligned top)
+ to be lighter than other borders.
+ We can fix it by using the darker bottom border below, but
+ then there are a few rogue pixels that end up very dark.
+ */
+ /* border-bottom: 1px solid rgba(15, 15, 15, 0.5); */
+ box-shadow: inset 0px 1px 0px rgba(255,255,255,0.2);
+ /**/
+ background: @onyx-button-background @onyx-button-gradient repeat-x bottom;
+ background-size: contain;
+ /**/
+ text-overflow: ellipsis;
+ /* the following cause arcane problems on IE */
+ /*
+ min-width: 14px;
+ min-height: 20px;
+ */
+}
+
+/*
+ IE8 can't handle these selectors in tandem:
+ .onyx-button.active, .onyx-button:active:not([disabled]) {
+
+ the effect is as if .onyx-button.active doesn't exist
+*/
+.onyx-button.active, .onyx-button.pressed {
+ background-image: @onyx-button-active-gradient;
+ background-position: top;
+ border-top: 1px solid rgba(15, 15, 15, 0.6);
+ box-shadow: inset 0px 1px 0px rgba(0,0,0,0.1);
+}
+
+.onyx-button:active:hover:not([disabled]) {
+ background-image: @onyx-button-active-gradient;
+ background-position: top;
+ border-top: 1px solid rgba(15, 15, 15, 0.6);
+ box-shadow: inset 0px 1px 0px rgba(0,0,0,0.1);
+}
+
+.onyx-button[disabled] {
+ opacity: @onyx-disabled-opacity;
+ filter: alpha(opacity=@onyx-disabled-opacity-ie);
+}
+
+.onyx-button > img {
+ padding: 0px 3px;
+}
+
+/* Remove the focused inner-border style in Firefox (Windows) */
+.onyx-button::-moz-focus-inner {
+ border: 0;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssButtonColorsless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/ButtonColors.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/ButtonColors.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/ButtonColors.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+/* ButtonColors.css */
+.onyx-button.onyx-blue {
+ background-color: #35A8EE;
+ color: #F2F2F2;
+}
+
+.onyx-button.onyx-affirmative {
+ background-color: #91BA07;
+ color: #F2F2F2;
+}
+
+.onyx-button.onyx-negative {
+ background-color: #C51616;
+ color: #F2F2F2;
+}
+
+.onyx-button.onyx-dark {
+ background-color: @onyx-dark-background;
+ color: #F2F2F2;
+}
+
+.onyx-button.onyx-light {
+ background-color: @onyx-light-background;
+ color: #2F2F2F;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssCheckboxless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Checkbox.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Checkbox.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Checkbox.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+/* Checkbox.css */
+.onyx-checkbox {
+ cursor: pointer;
+ height: @onyx-checkbox-image-height;
+ width: @onyx-checkbox-image-width;
+ background: @onyx-checkbox-image no-repeat;
+ /* reset for ? */
+ margin: 0px;
+ /* these entries cause toggle-button and checkbox to line up properly*/
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.onyx-checkbox[checked] {
+ background-position: 0px -@onyx-checkbox-image-height;
+}
+
+.onyx-checkbox[disabled] {
+ opacity: @onyx-disabled-opacity;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssContextualPopupless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/ContextualPopup.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/ContextualPopup.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/ContextualPopup.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,230 @@
</span><ins>+/* ContextualPopup.css */
+.onyx-contextual-popup-title {
+ font-weight:bold;
+ padding:24px 32px 0px;
+}
+.onyx-contextual-popup-scroller {
+ padding:24px 32px;
+}
+.onyx-contextual-popup-action-buttons {
+ display:inline-block;
+ width:100%;
+ text-align: center;
+}
+.onyx-contextual-popup-action-button {
+ margin-left: 5px;
+ margin-right: 5px;
+}
+.onyx-contextual-popup,
+.onyx.onyx-contextual-popup {
+ font-size: 16px;
+ box-shadow: 0 6px 10px rgba(0, 0, 0, 0.2);
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 8px;
+ padding: 6px;
+ color: #ffffff;
+ background: #4c4c4c;
+}
+/*setup the nub*/
+.onyx-contextual-popup::after{
+ content: '';
+ position: absolute;
+ top: -10px;
+ border-left: 10px solid transparent;
+ border-right: 10px solid transparent;
+ border-top: 10px solid transparent;
+ border-bottom: 10px solid transparent;
+}
+/*for popups above activator*/
+.onyx-contextual-popup.vertical.above {
+ top: auto;
+ margin-top:-10px;
+ bottom: 100%;
+ margin-bottom: 10px;
+}
+/*for popups below activator*/
+.onyx-contextual-popup.vertical.below {
+ margin-top:10px;
+}
+/*for popups on the left of the activator*/
+.onyx-contextual-popup.right.horizontal {
+ margin-left: -11px;
+}
+/*for popups on the right of the activator*/
+.onyx-contextual-popup.left.horizontal {
+ margin-left: 10px;
+}
+/*nub positioning*/
+/*horizontally centered nub*/
+.onyx-contextual-popup.vertical::after {
+ position:absolute;
+ left:45%;
+ border-bottom: 10px solid #4c4c4c;
+ border-top: none;
+ border-left: 10px solid transparent;
+ border-right: 10px solid transparent;
+}
+/*nub near horizontal left*/
+.onyx-contextual-popup.vertical.right::after {
+ left:0%;
+ margin-left:20px;
+}
+/*nub near horizontal right*/
+.onyx-contextual-popup.vertical.left::after {
+ left:100%;
+ margin-left: -55px;
+}
+/*downward facing nub*/
+.onyx-contextual-popup.vertical.above::after {
+ top:100%;
+ border-top: 10px solid #4c4c4c;
+ border-bottom: none;
+ border-left: 10px solid transparent;
+ border-right: 10px solid transparent;
+}
+.onyx-contextual-popup.vertical.below.right::after {
+ top:0%;
+ margin-top:-10px;
+ border-bottom: 10px solid #4c4c4c;
+ border-left: 10px solid transparent;
+}
+.onyx-contextual-popup.vertical.below.left::after {
+ top:0%;
+ margin-top:-10px;
+ border-right: 10px solid transparent;
+}
+/*nub positioning for left/right popups*/
+/*vertically centered nub for popups on left of activator*/
+.onyx-contextual-popup.right::after {
+ left: 100%;
+ top:47%;
+ margin-right:20px;
+ border-left: 10px solid #4C4C4C;
+}
+/*nub near vertical top for popups on left of activator*/
+.onyx-contextual-popup.right.high::after {
+ top: 35px;
+ border-left: 10px solid #4C4C4C;
+}
+/*nub near vertical bottom for popups on left of activator*/
+.onyx-contextual-popup.right.low::after {
+ top:100%;
+ margin-top: -55px;
+ border-left: 10px solid #4C4C4C;
+}
+/*vertically centered nub for popups on right of activator*/
+.onyx-contextual-popup.left::after {
+ left: 0%;
+ margin-left: -20px;
+ top: 45%;
+ border-right: 10px solid #4C4C4C;
+}
+/*nub near vertical top for popups on right of activator*/
+.onyx-contextual-popup.left.high::after {
+ top: 35px;
+ border-right: 10px solid #4C4C4C;
+}
+/*nub near vertical bottom for popups on right of activator*/
+.onyx-contextual-popup.left.low::after {
+ top:100%;
+ margin-top: -55px;
+ border-right: 10px solid #4C4C4C;
+}
+/*corners*/
+/*vertical top corners*/
+/*for popups on the left of the activator*/
+.onyx-contextual-popup.vertical.right.corner {
+ margin-left: 0px;
+}
+/*for popups on the right of the activator*/
+.onyx-contextual-popup.vertical.left.corner {
+ margin-left: 0px;
+}
+.onyx-contextual-popup.vertical.below.left.corner {
+ border-top-right-radius: 0px;
+}
+.onyx-contextual-popup.vertical.below.right.corner {
+ border-top-left-radius: 0px;
+}
+.onyx-contextual-popup.vertical.below.left.corner::after {
+ top:0%;
+ left:100%;
+ margin-top:-10px;
+ margin-left:-19px;
+ border-right: 10px solid #4c4c4c;
+ border-top: 10px solid transparent;
+}
+.onyx-contextual-popup.vertical.below.right.corner::after {
+ top:0%;
+ left:0%;
+ margin-left: -1px;
+ border-left: 10px solid #4c4c4c;
+ border-top: 10px solid transparent;
+}
+/*vertical bottom corners*/
+.onyx-contextual-popup.left.above.corner {
+ border-bottom-right-radius: 0px;
+}
+.onyx-contextual-popup.right.above.corner {
+ border-bottom-left-radius: 0px;
+}
+.onyx-contextual-popup.vertical.left.above.corner::after {
+ top:100%;
+ margin-left:-19px;
+ border-right: 10px solid #4C4C4C;
+ border-bottom: 10px solid transparent;
+ border-top: none;
+}
+.onyx-contextual-popup.vertical.right.above.corner::after {
+ top:100%;
+ left:0%;
+ margin-left: -1px;
+ border-left: 10px solid #4c4c4c;
+ border-bottom: 10px solid transparent;
+ border-top: none;
+}
+/*horizontal bottom corners*/
+.onyx-contextual-popup.left.low.corner {
+ border-bottom-left-radius: 0px;
+}
+.onyx-contextual-popup.right.low.corner {
+ border-bottom-right-radius: 0px;
+}
+.onyx-contextual-popup.left.low.corner::after {
+ top:100%;
+ left:0%;
+ margin-top: -19px;
+ margin-left: -12px;
+ border-bottom: 10px solid #4c4c4c;
+ border-right: 10px solid #4c4c4c;
+}
+.onyx-contextual-popup.right.low.corner::after {
+ top:100%;
+ left:100%;
+ margin-top: -19px;
+ border-bottom: 10px solid#4c4c4c;
+ border-left: none;
+}
+/*horizontal top corners*/
+.onyx-contextual-popup.left.high.corner {
+ border-top-left-radius: 0px;
+}
+.onyx-contextual-popup.right.high.corner {
+ border-top-right-radius: 0px;
+}
+.onyx-contextual-popup.left.high.corner::after {
+ top:0%;
+ left:0%;
+ margin-top: -1px;
+ margin-left: -12px;
+ border-top: 10px solid #4C4C4C;
+ border-bottom: none;
+}
+.onyx-contextual-popup.right.high.corner::after {
+ top:0%;
+ left:100%;
+ margin-top:-1px;
+ margin-left:-9px;
+ border-top: 10px solid #4C4C4C;
+ border-bottom: none;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssDatePickerless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/DatePicker.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/DatePicker.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/DatePicker.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+/* DatePicker.css */
+.onyx-datepicker-month {
+ min-width: 75px;
+}
+
+.onyx-datepicker-day {
+ min-width: 60px;
+}
+
+.onyx-datepicker-year {
+ min-width: 70px;
+}
+
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssGrabberless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Grabber.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Grabber.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Grabber.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+/* Grabber.css */
+.onyx-grabber {
+ background: @onyx-grabber-image no-repeat center;
+ width: @onyx-grabber-image-width;
+ height: @onyx-grabber-image-height;
+}
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssGroupboxless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Groupbox.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Groupbox.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Groupbox.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,67 @@
</span><ins>+/* Groupbox.css */
+.onyx-groupbox {
+}
+
+.onyx-groupbox > * {
+ display: block;
+ /*box-shadow: inset 0px 1px 1px rgba(255,255,255,0.5);*/
+ border-color: #aaaaaa;
+ border-style: solid;
+ border-width: 0 1px 1px 1px;
+ /*padding: 10px;*/
+ /* reset styles that make 'item' look bad if they happen to be there */
+ border-radius: 0;
+ margin: 0;
+ font-size: @onyx-groupbox-font-size;
+}
+
+.onyx-groupbox > *:first-child {
+ border-top-color: #aaaaaa;
+ border-width: 1px;
+ border-radius: @onyx-groupbox-border-radius @onyx-groupbox-border-radius 0 0;
+}
+
+.onyx-groupbox > *:last-child {
+ border-radius: 0 0 @onyx-groupbox-border-radius @onyx-groupbox-border-radius;
+}
+
+.onyx-groupbox > *:first-child:last-child {
+ border-radius: @onyx-groupbox-border-radius;
+}
+
+.onyx-groupbox-header {
+ padding: 2px 10px;
+ /**/
+ color: @onyx-groupbox-text-color;
+ font-size: @onyx-groupbox-header-font-size;
+ font-weight: bold;
+ text-transform: uppercase;
+ /**/
+ background-color: @onyx-groupbox-background;
+ border: none;
+ background: @onyx-groupbox-background @onyx-groupbox-gradient repeat-x 0 10px;
+}
+
+.onyx-groupbox .onyx-input-decorator {
+ display: block;
+}
+
+.onyx-groupbox > .onyx-input-decorator {
+ border-color: #aaaaaa;
+ border-width: 0 1px 1px 1px;
+ border-radius: 0;
+}
+
+.onyx-groupbox > .onyx-input-decorator:first-child {
+ border-width: 1px;
+ border-radius: @onyx-groupbox-border-radius @onyx-groupbox-border-radius 0 0;
+}
+
+.onyx-groupbox > .onyx-input-decorator:last-child {
+ border-radius: 0 0 @onyx-groupbox-border-radius @onyx-groupbox-border-radius;
+}
+
+.onyx-groupbox > .onyx-input-decorator:first-child:last-child {
+ border-radius: @onyx-groupbox-border-radius;
+}
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssIconless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Icon.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Icon.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Icon.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+/* Icon.css */
+.onyx-icon, .onyx-icon-toggle {
+ width: @onyx-icon-size;
+ height: @onyx-icon-size;
+ background-repeat: no-repeat;
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.onyx-icon.onyx-icon-button.active, .onyx-icon.onyx-icon-button.pressed, .onyx-icon.onyx-icon-button:active:hover, .onyx-icon-toggle.active {
+ background-position: 0 -@onyx-icon-size;
+}
+
+.onyx-icon.disabled {
+ opacity: @onyx-disabled-opacity;
+ filter: alpha(opacity=@onyx-disabled-opacity-ie);
+}
+
+.onyx-icon.disabled:active:hover {
+ background-position: 0 0px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssInputless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Input.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Input.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Input.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+/* Input.css */
+.onyx-input-decorator {
+ padding: 6px 8px 10px 8px;
+ border-radius: @onyx-input-border-radius;
+ border: 1px solid;
+ border-color: rgba(0,0,0,0.1);
+ margin: 0;
+}
+
+.onyx-input-decorator.onyx-focused {
+ box-shadow: inset 0px 1px 4px rgba(0,0,0,0.3);
+ border-color: rgba(0,0,0,0.3);
+ background-color: @onyx-input-focused-background;
+}
+
+.onyx-input-decorator.onyx-disabled {
+ /* FIXME: needed to color a disabled input placeholder. */
+ /*-webkit-text-fill-color: #888;*/
+ opacity: @onyx-disabled-opacity;
+ filter: alpha(opacity=@onyx-disabled-opacity-ie);
+}
+
+.onyx-input-decorator > input {
+ /* reset */
+ margin: 0;
+ padding: 0;
+ border: none;
+ outline: none;
+ cursor: pointer;
+ background-color: @onyx-input-background;
+ background-image: none;
+ font-size: @onyx-input-font-size;
+ box-shadow: none;
+ /* FIXME: hack for styling reset on Android */
+ /* -webkit-appearance: caret;*/
+}
+
+.onyx-input-decorator.onyx-focused > input {
+ cursor: text;
+}
+
+.onyx-input-decorator.onyx-disabled > input {
+ cursor: default;
+}
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssItemless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Item.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Item.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Item.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+/* Item.css */
+.onyx-item {
+ padding: 14px;
+}
+
+.onyx-highlight, .onyx-highlight.onyx-swipeable-item-content {
+ background-color: @onyx-highlight-background;
+}
+
+.enyo-selected, .enyo-selected.onyx-swipeable-item-content {
+ background-color: @onyx-selected-background;
+}
+
+.onyx-item.onyx-swipeable-item {
+ overflow: hidden;
+ padding: 0;
+}
+
+.onyx-swipeable-item-content {
+ background-color: @onyx-switeable-item-background;
+ box-sizing: border-box;
+ padding: 18px 6px;
+ min-height: 40px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssMenuless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Menu.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Menu.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Menu.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+/* Menu.css */
+.onyx-menu, .onyx.onyx-menu {
+ min-width: 160px;
+ top: 100%;
+ left: 0;
+ margin-top: 2px;
+ padding: 3px 0;
+ border-radius: @onyx-menu-border-radius;
+}
+
+.onyx-menu.onyx-menu-up {
+ top: auto;
+ bottom: 100%;
+ margin-top: 0;
+ margin-bottom: 2px;
+}
+
+.onyx-toolbar .onyx-menu {
+ margin-top: 11px;
+ border-radius: 0 0 @onyx-menu-border-radius @onyx-menu-border-radius;
+}
+
+
+.onyx-toolbar .onyx-menu.onyx-menu-up {
+ margin-top: 0;
+ margin-bottom: 10px;
+ border-radius: @onyx-menu-border-radius @onyx-menu-border-radius 0 0;
+}
+
+.onyx-menu-item {
+ display: block;
+ padding: 10px;
+}
+
+.onyx-menu-item:hover {
+ background: @onyx-menu-item-hover;
+}
+
+.onyx-menu-divider, .onyx-menu-divider:hover {
+ margin: 6px 0;
+ padding: 0;
+ border-bottom: 1px solid #aaa;
+}
+
+.onyx-menu-label {
+ cursor: default;
+ -webkit-user-select: none;
+ -moz-user-select: -moz-none;
+ user-select: none;
+ opacity: @onyx-disabled-opacity;
+ filter: alpha(opacity=@onyx-disabled-opacity-ie);
+}
+
+.onyx-menu-label:hover {
+ background: none;
+}
+
+/* customize a toolbar to support menus */
+.onyx-menu-toolbar, .onyx-toolbar.onyx-menu-toolbar {
+ position: relative;
+ z-index: 10;
+ overflow: visible;
+}
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssMoreToolbarless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/MoreToolbar.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/MoreToolbar.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/MoreToolbar.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+/* MoreToolbar.css */
+.onyx-more-toolbar {
+ overflow: visible;
+ position: relative;
+ z-index: 10;
+}
+
+.onyx-more-toolbar.active {
+ z-index:11;
+}
+
+.onyx-more-menu {
+ left: auto;
+ right: 0px;
+ min-width: 0;
+}
+
+.onyx-more-toolbar .onyx-more-menu > * {
+ float: right;
+ clear: both;
+ margin: 5px;
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+
+.onyx-more-button {
+ background-image: @onyx-more-toolbar-button-image;
+ width: @onyx-more-toolbar-button-image-width;
+ height: @onyx-more-toolbar-button-image-height;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssPickerless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Picker.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Picker.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Picker.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+/* Picker.css */
+.onyx-picker-decorator .onyx-button {
+ padding: 10px 18px;
+}
+
+.onyx-picker {
+ top: 0;
+ margin-top: -3px;
+ min-width: 0;
+ width: 100%;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ color: black;
+ background: @onyx-picker-background;
+}
+
+.onyx-picker.onyx-menu-up {
+ top: auto;
+ bottom: 0;
+ margin-top: 3px;
+ margin-bottom: -3px;
+}
+
+.onyx-picker .onyx-menu-item {
+ text-align: center;
+}
+
+.onyx-picker .onyx-menu-item:hover {
+ background-color: transparent;
+}
+
+.onyx-picker .onyx-menu-item.selected, .onyx-picker .onyx-menu-item.active, .onyx-picker .onyx-menu-item:active:hover {
+ border-top: 1px solid rgba(0, 0, 0, 0.1);
+ background-color: @onyx-picker-item-background;
+ box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.2);
+}
+
+.onyx-picker .onyx-menu-item {
+ border-top: 1px solid rgba(255,255,255,0.5);
+ border-bottom: 1px solid rgba(0,0,0,0.2);
+}
+
+.onyx-picker:not(.onyx-flyweight-picker) .onyx-menu-item:first-child, .onyx-flyweight-picker :first-child > .onyx-menu-item {
+ border-top: none;
+}
+
+.onyx-picker:not(.onyx-flyweight-picker) .onyx-menu-item:last-child, .onyx-flyweight-picker :last-child > .onyx-menu-item {
+ border-bottom: none;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssPopupless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Popup.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Popup.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Popup.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+/* Popup.css */
+.onyx-popup {
+ font-size: @onyx-popup-font-size;
+ box-shadow: 0 6px 10px rgba(0, 0, 0, 0.2);
+ border: 1px solid rgba(0,0,0,0.2);
+ border-radius: 8px;
+ padding: 6px;
+ color: @onyx-popup-text-color;
+ background: @onyx-popup-background @onyx-button-gradient repeat-x 0 bottom;
+}
+
+.onyx-popup-decorator {
+ position: relative;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssProgressBarless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/ProgressBar.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/ProgressBar.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/ProgressBar.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+/* ProgressBar.css */
+.onyx-progress-bar {
+ margin: 8px;
+ height: 8px;
+ border: 1px solid rgba(15, 15, 15, 0.2);
+ border-radius: @onyx-progressbar-border-radius;
+ background: @onyx-progressbar-background @onyx-progressbar-gradient repeat-x;
+ background-size: auto 100%;
+}
+
+.onyx-progress-bar-bar {
+ height: 100%;
+ border-radius: @onyx-progressbar-border-radius;
+ background: @onyx-progressbar-bar-background @onyx-progressbar-bar-gradient repeat-x;
+ background-size: auto 100%;
+}
+
+.onyx-progress-bar-bar.striped {
+ background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-size: 40px 40px;
+}
+
+.onyx-progress-bar-bar.striped.animated {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -moz-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 0 0;
+ }
+ to {
+ background-position: 40px 0;
+ }
+}
+
+@-moz-keyframes progress-bar-stripes {
+ from {
+ background-position: 0 0;
+ }
+ to {
+ background-position: 40px 0;
+ }
+}
+
+@-o-keyframes progress-bar-stripes {
+ from {
+ background-position: 0 0;
+ }
+ to {
+ background-position: 40px 0;
+ }
+}
+
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 0 0;
+ }
+ to {
+ background-position: 40px 0;
+ }
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssProgressButtonless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/ProgressButton.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/ProgressButton.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/ProgressButton.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+/* ProgressButton.css */
+.onyx-progress-button {
+ position: relative;
+ height: 36px;
+ line-height: 36px;
+ color: @onyx-progressbutton-text-color;
+ font-size: @onyx-progressbutton-font-size;
+ text-overflow: ellipsis;
+}
+
+.onyx-progress-button-bar {
+ height: 36px;
+}
+
+.onyx-progress-button-icon {
+ display: inline-block;
+ position: absolute;
+ top: 2px;
+ right: 0;
+}
+
+.onyx-progress-button-client {
+ display: inline-block;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 36px;
+ margin-left: 8px;
+}
+
+.onyx-progress-button-client > * {
+ display: inline-block;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssRadioButtonless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/RadioButton.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/RadioButton.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/RadioButton.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+/* RadioButton.css */
+.onyx-radiobutton {
+ padding: 8px 12px;
+ margin: 0;
+ outline: 0;
+ /**/
+ font-size: @onyx-radiobutton-font-size;
+ text-shadow: 0 1px 1px rgba(0,0,0,0.2);
+ text-align: center;
+ /**/
+ background: @onyx-radiobutton-background @onyx-radiobutton-gradient repeat-x bottom;
+ /* IE8 */
+ border: 1px solid (@onyx-radiobutton-background * 0.22);
+ border: 1px solid fade((@onyx-radiobutton-background * 0.065), 20%);
+ /* turn off right-border in a way IE8 ignores, because IE8 does not support :last-child */
+ border-right-color: rgba(0,0,0,0);
+ box-shadow: inset 1px 1px 0px rgba(255, 255, 255, 0.2);
+}
+
+.onyx-radiobutton:first-child {
+ border-radius: @onyx-radiobutton-border-radius 0 0 @onyx-radiobutton-border-radius;
+}
+
+.onyx-radiobutton:last-child {
+ border-radius: 0px @onyx-radiobutton-border-radius @onyx-radiobutton-border-radius 0px;
+ /* IE8 */
+ border-right: 1px solid (@onyx-radiobutton-background * 0.22);
+ border-right: 1px solid fade((@onyx-radiobutton-background * 0.065), 20%);
+}
+
+.onyx-radiobutton.active {
+ color: @onyx-radiobutton-active-text-color;
+ background: @onyx-radiobutton-active-background @onyx-gradient-invert repeat-x top;
+ border-top: 1px solid fade((@onyx-radiobutton-background * 0.065), 60%);
+ box-shadow: inset 1px 2px 2px rgba(0, 0, 0, 0.2);
+}
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssRangeSliderless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/RangeSlider.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/RangeSlider.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/RangeSlider.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+/* RangeSlider.css */
+.onyx-range-slider-knob {
+ top: -17px;
+}
+.onyx-range-slider-label {
+ position: relative;
+ top: -18px;
+ text-align: center;
+ white-space: nowrap;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssRichTextless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/RichText.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/RichText.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/RichText.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+/* RichText.css */
+.onyx-input-decorator > .onyx-richtext {
+ /* reset */
+ margin: 0;
+ padding: 0;
+ border: none;
+ outline: none;
+ cursor: pointer;
+ background-color: @onyx-input-background;
+ background-image: none;
+ font-size: @onyx-richtext-font-size;
+ min-height: 20px;
+ min-width: 100px;
+ box-shadow: none;
+ /* FIXME: hack for styling reset on Android */
+ /* -webkit-appearance: caret;*/
+}
+
+.onyx-input-decorator.onyx-focused > .onyx-richtext {
+ cursor: text;
+}
+
+.onyx-input-decorator.onyx-disabled > .onyx-richtext {
+ cursor: default;
+}
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssScrimless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Scrim.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Scrim.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Scrim.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+/* Scrim.css */
+.onyx-scrim {
+ z-index: 1;
+ /*
+ note: by using pointer-events we allow tapping on scrim
+ while it is fading out; however, this requires any showing classes
+ to set pointer events to auto or scrim will not function as expected.
+ */
+ pointer-events: none;
+}
+
+@onyx-scrim-opacity-ie: @onyx-scrim-opacity*100;
+.onyx-scrim.onyx-scrim-translucent{
+ pointer-events: auto;
+ background-color: @onyx-scrim-background;
+ opacity: @onyx-scrim-opacity;
+ filter: alpha(opacity=@onyx-scrim-opacity-ie);
+}
+
+.onyx-scrim.onyx-scrim-transparent {
+ pointer-events: auto;
+ background: transparent;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssSliderless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Slider.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Slider.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Slider.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+/* Slider.css */
+.onyx-slider {
+ position: relative;
+ margin: 8px 20px;
+}
+
+.onyx-slider-taparea {
+ position: absolute;
+ top: -11px;
+ height: 28px;
+ width: 100%;
+}
+
+.onyx-slider-knob {
+ position: relative;
+ height: @onyx-slider-knob-image-height;
+ width: @onyx-slider-knob-image-width;
+ background: @onyx-slider-knob-image left top no-repeat;
+ margin: -23px -20px;
+}
+
+.onyx-slider-knob.active, .onyx-slider-knob.pressed, .onyx-slider-knob:active:hover {
+ background-position: 0 -40px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssSpinnerless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Spinner.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Spinner.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Spinner.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+/* Spinner.css */
+.onyx-spinner {
+ width: @onyx-spinner-image-width;
+ height: @onyx-spinner-image-height;
+ display: inline-block;
+ background: @onyx-spinner-dark-image no-repeat 0 0;
+}
+
+.onyx-spinner.onyx-light {
+ background: @onyx-spinner-light-image no-repeat 0 0;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssTabButtonless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/TabButton.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/TabButton.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/TabButton.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+/* TabButton.css */
+.onyx-radiobutton.onyx-tabbutton {
+ padding: @onyx-tabbutton-padding-tb @onyx-tabbutton-padding-lr;
+ font-size: @onyx-tabbutton-font-size;
+ border-radius: 0px;
+}
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssTextArealess"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/TextArea.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/TextArea.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/TextArea.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+/* TextArea.css */
+.onyx-input-decorator > textarea {
+ /* reset */
+ margin: 0;
+ padding: 0;
+ border: none;
+ outline: none;
+ cursor: pointer;
+ background-color: @onyx-input-background;
+ background-image: none;
+ font-size: @onyx-textarea-font-size;
+ box-shadow: none;
+ /* Remove scrollbars and resize handle */
+ resize: none;
+ overflow: auto;
+ /* FIXME: hack for styling reset on Android */
+ /* -webkit-appearance: caret;*/
+}
+
+.onyx-input-decorator.onyx-focused > textarea {
+ cursor: text;
+}
+
+.onyx-input-decorator.onyx-disabled > textarea {
+ cursor: default;
+}
+
+.onyx-textarea {
+ /* need >=50px for scrollbar to be usable on mac */
+ min-height: 50px;
+}
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssTimePickerless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/TimePicker.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/TimePicker.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/TimePicker.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+/* TimePicker.css */
+.onyx-timepicker-hour {
+ min-width: 60px;
+}
+
+.onyx-timepicker-minute {
+ min-width: 60px;
+}
+
+.onyx-timepicker-ampm {
+ min-width: 60px;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssToggleButtonless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/ToggleButton.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/ToggleButton.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/ToggleButton.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+/* ToggleButton.css */
+.onyx-toggle-button {
+ display: inline-block;
+ height: 32px;
+ line-height: 32px;
+ min-width: 64px;
+ vertical-align: middle;
+ text-align: center;
+ /* */
+ border-radius: @onyx-togglebutton-border-radius;
+ box-shadow: inset 0px 1px 3px rgba(0,0,0,0.4);
+ background: @onyx-togglebutton-background @onyx-togglebutton-gradient repeat-x bottom;
+ background-size: auto 100%;
+ /* label */
+ color: @onyx-togglebutton-text-color;
+ font-size: @onyx-togglebutton-font-size;
+ font-weight: bold;
+ text-transform: uppercase;
+}
+
+.onyx-toggle-button.off {
+ background-color: @onyx-togglebutton-off-background !important;
+}
+
+.onyx-toggle-button-knob {
+ display: inline-block;
+ width: 30px;
+ height: 30px;
+ margin: 1px;
+ border-radius: @onyx-togglebutton-border-radius;
+ background: @onyx-togglebutton-knob-background @onyx-togglebutton-knob-gradient repeat-x;
+ background-size: auto 100%;
+}
+
+.onyx-toggle-button .onyx-toggle-button-knob {
+ box-shadow: -1px 0px 4px rgba(0,0,0,0.35), inset 0 -1px 0 rgba(0,0,0,0.4);
+ float: right;
+}
+
+.onyx-toggle-button.off .onyx-toggle-button-knob {
+ box-shadow: 1px 0px 4px rgba(0,0,0,0.35), inset 0 -1px 0 rgba(0,0,0,0.4);
+ float: left;
+}
+
+.onyx-toggle-button.disabled, .onyx-icon-button.disabled {
+ opacity: @onyx-disabled-opacity;
+ filter: alpha(opacity=@onyx-disabled-opacity-ie);
+}
+
+.onyx-toggle-content {
+ min-width: 32px;
+ padding: 0 6px;
+}
+
+.onyx-toggle-content.empty {
+ padding: 0;
+}
+
+.onyx-toggle-content.off {
+ float: right;
+}
+
+.onyx-toggle-content.on {
+ float: left;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssToolbarless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Toolbar.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Toolbar.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Toolbar.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+/* Toolbar.css */
+.onyx-toolbar {
+ /*
+ line-height is unreliable for centering, instead
+ use vertical-align: middle to align
+ elements along a common centerline and use
+ padding to fill out the space.
+ */
+ padding: 9px 8px 10px 8px;
+ /**/
+ border: 1px solid #3A3A3A;
+ background: @onyx-toolbar-background @onyx-toolbar-gradient repeat-x 0 bottom;
+ background-size: contain;
+ color: @onyx-toolbar-text-color;
+ /**/
+ white-space: nowrap;
+ overflow-y: visible;
+ font-size: @onyx-toolbar-font-size;
+}
+
+.onyx-toolbar-inline > *, .enyo-fittable-columns-layout.onyx-toolbar-inline > * {
+ display: inline-block;
+ vertical-align: middle;
+ margin: 4px 6px 5px;
+ box-sizing: border-box;
+}
+
+.onyx-toolbar .onyx-icon-button {
+ margin: 3px 2px 1px;
+}
+
+.onyx-toolbar .onyx-button {
+ color: @onyx-toolbar-button-text-color;
+ background-color: @onyx-toolbar-button-background;
+ border-color: rgba(15, 15, 15, 0.5);
+ margin-top: 0;
+ margin-bottom: 0;
+ height: 36px;
+}
+
+.onyx-toolbar .onyx-input-decorator {
+ margin: 1px 3px;
+ box-shadow: inset 0px 1px 4px rgba(0,0,0,0.1);
+ background-color: @onyx-toolbar-input-background;
+ padding: 0px 6px 5px 6px;
+}
+
+.onyx-toolbar .onyx-input-decorator.onyx-focused {
+ box-shadow: inset 0px 1px 4px rgba(0,0,0,0.3);
+ background-color: @onyx-toolbar-input-focused-background;
+}
+
+.onyx-toolbar .onyx-input-decorator .onyx-input {
+ color: @onyx-toolbar-input-text-color;
+ font-size: @onyx-toolbar-input-font-size;
+}
+
+.onyx-toolbar .onyx-input-decorator .onyx-input:focus {
+ color: @onyx-toolbar-input-focus-text-color;
+}
+
+.onyx-toolbar .onyx-input-decorator .onyx-input:focus::-webkit-input-placeholder {
+ color: @onyx-toolbar-input-placeholder-text-color;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssTooltipless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/Tooltip.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/Tooltip.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/Tooltip.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,70 @@
</span><ins>+/* Tooltip.css */
+.onyx-tooltip {
+ z-index: 20;
+ left: 0;
+ padding: 4px 6px;
+ margin-top: 4px;
+ margin-left: -6px;
+ box-shadow: 0 6px 10px rgba(0, 0, 0, 0.2);
+ border: 1px solid rgba(0,0,0,0.2);
+ color: @onyx-tooltip-text-color;
+ background: @onyx-tooltip-background @onyx-tooltip-gradient repeat-x 0 bottom;
+ border-radius: @onyx-tooltip-border-radius;
+ white-space: nowrap;
+}
+
+/*move the tooltip over to the right when displaying the right arrow so it aligns better with the decorator*/
+.onyx-tooltip.right-arrow {
+ left: 30px;
+}
+
+/*prep the left & right arrows using before & after - left arrow uses before & right arrow uses after*/
+.onyx-tooltip::before {
+ content: '';
+ border-left: 6px solid transparent;
+ border-right: 6px solid transparent;
+ position: absolute;
+ top: -6px;
+ left: 16px;
+}
+
+.onyx-tooltip::after {
+ content: '';
+ border-left: 6px solid transparent;
+ border-right: 6px solid transparent;
+ position: absolute;
+ top: -6px;
+ margin-left: -12px;
+}
+
+/*The following 3 rules handle the left & right arrows when the tooltip is displayed below the activator*/
+.onyx-tooltip.below {
+ top: 100%;
+}
+
+.onyx-tooltip.below.right-arrow::after {
+ border-bottom: 6px solid #1D587F;
+ top: -6px;
+}
+
+.onyx-tooltip.below.left-arrow::before {
+ border-bottom: 6px solid #1D587F;
+ top: -6px;
+}
+
+/*The following 3 rules handle the left & right arrows when the tooltip is displayed above the activator*/
+.onyx-tooltip.above {
+ top: -100%;
+}
+
+.onyx-tooltip.above.right-arrow::after {
+ content: '';
+ border-top: 6px solid #1D587F;
+ top: 100%;
+}
+
+.onyx-tooltip.above.left-arrow::before {
+ content: '';
+ border-top: 6px solid #1D587F;
+ top: 100%;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssonyxrulesless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/onyx-rules.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/onyx-rules.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/onyx-rules.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+/* onyx-classes.less - combined CSS (less) files for all released Onyx controls
+ into single onyx.less file to avoid IE bug that allows
+ a maximum of 31 style sheets to be loaded before silently failing */
+
+.onyx {
+ color: @onyx-text-color;
+ font-family: @onyx-font-family;
+ font-size: @onyx-font-size;
+ cursor: default;
+ background-color: @onyx-background;
+ /* remove automatic tap highlight color */
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+/* prevent IE from inheriting line-height for these elements */
+.onyx button, .onyx label, .onyx input {
+ line-height: normal;
+}
+
+.onyx-selected {
+ background-color: @onyx-selected-background;
+}
+
+/* LESS pre-calculations */
+@onyx-disabled-opacity-ie: @onyx-disabled-opacity*100;
+
+
+/* Individual Widget CSS */
+
+@import "Icon.less";
+@import "Button.less";
+@import "Checkbox.less";
+@import "Grabber.less";
+@import "Popup.less";
+@import "Groupbox.less";
+@import "Input.less";
+@import "Menu.less";
+@import "Picker.less";
+@import "TextArea.less";
+@import "RichText.less";
+@import "RadioButton.less";
+@import "Scrim.less";
+@import "TabButton.less";
+@import "ToggleButton.less";
+@import "Toolbar.less";
+@import "Tooltip.less";
+@import "ProgressBar.less";
+@import "ProgressButton.less";
+@import "Slider.less";
+@import "RangeSlider.less";
+@import "Item.less";
+@import "Spinner.less";
+@import "MoreToolbar.less";
+@import "DatePicker.less";
+@import "TimePicker.less";
+@import "ButtonColors.less";
+@import "ContextualPopup.less";
+
+/* some default colors */
+.onyx-dark {
+ background-color: @onyx-dark-background;
+}
+
+.onyx-light {
+ background-color: @onyx-light-background;
+}
+
+.onyx-green {
+ background-color: #91BA07;
+}
+
+.onyx-red {
+ background-color: #C51616;
+}
+
+.onyx-blue {
+ background-color: #35A8EE;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssonyxvariablesless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/onyx-variables.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/onyx-variables.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/onyx-variables.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,140 @@
</span><ins>+/* Fonts */
+/* ---------------------------------------*/
+@onyx-font-family: 'Helvetica Neue', 'Nimbus Sans L', Arial, sans-serif;
+@onyx-font-size-small: 14px;
+@onyx-font-size-medium: 16px;
+@onyx-font-size-large: 20px;
+
+@onyx-button-font-size: @onyx-font-size-medium;
+@onyx-font-size: @onyx-font-size-large;
+@onyx-groupbox-font-size: @onyx-font-size-medium;
+@onyx-groupbox-header-font-size: @onyx-font-size-small;
+@onyx-input-font-size: @onyx-font-size-medium;
+@onyx-popup-font-size: @onyx-font-size-medium;
+@onyx-progressbutton-font-size: @onyx-font-size-medium;
+@onyx-radiobutton-font-size: @onyx-font-size-medium;
+@onyx-richtext-font-size: @onyx-font-size-medium;
+@onyx-tabbutton-font-size: @onyx-font-size-large;
+@onyx-textarea-font-size: @onyx-font-size-medium;
+@onyx-togglebutton-font-size: @onyx-font-size-small;
+@onyx-toolbar-font-size: @onyx-font-size-large;
+@onyx-toolbar-input-font-size: @onyx-font-size-small;
+
+/* Text Colors */
+/* ---------------------------------------*/
+@onyx-button-text-color: #292929;
+@onyx-groupbox-text-color: white;
+@onyx-picker-text-color: black;
+@onyx-popup-text-color: white;
+@onyx-progressbutton-text-color: #F1F1F1;
+@onyx-radiobutton-active-text-color: white;
+@onyx-text-color: #333333;
+@onyx-togglebutton-text-color: white;
+@onyx-toolbar-button-text-color: #F2F2F2;
+@onyx-toolbar-input-focus-text-color: #000;
+@onyx-toolbar-input-placeholder-text-color: #ddd;
+@onyx-toolbar-input-text-color: #e5e5e5;
+@onyx-toolbar-text-color: white;
+@onyx-tooltip-text-color: white;
+
+/* Background Colors */
+/* ---------------------------------------*/
+@onyx-background: #EAEAEA;
+@onyx-light-background: #CACACA;
+@onyx-dark-background: #555656;
+@onyx-selected-background: #C4E3FE;
+
+@onyx-button-background: #E1E1E1;
+@onyx-groupbox-background: #4C4C4C;
+@onyx-highlight-background: #DEDFDF;
+@onyx-input-background: transparent;
+@onyx-input-focused-background: white;
+@onyx-menu-item-hover: #284152;
+@onyx-picker-background: #E1E1E1;
+@onyx-picker-item-background: #cde7fe;
+@onyx-popup-background: #4C4C4C;
+@onyx-progressbar-background: #B8B8B8;
+@onyx-progressbar-bar-background: #58ABEF;
+@onyx-radiobutton-active-background: #0091F2;
+@onyx-radiobutton-background: #E7E7E7;
+@onyx-scrim-background: black;
+@onyx-scrim-opacity: 0.65;
+@onyx-switeable-item-background: #EAEAEA;
+@onyx-togglebutton-background: #8BBA3D;
+@onyx-togglebutton-knob-background: #F6F6F6;
+@onyx-togglebutton-off-background: #B1B1B1;
+@onyx-toolbar-background: #4C4C4C;
+@onyx-toolbar-button-background: #555656;
+@onyx-toolbar-input-background: rgba(0, 0, 0, 0.1);
+@onyx-toolbar-input-focused-background: white;
+@onyx-tooltip-background: #216593;
+
+/* Border Radius */
+/* ---------------------------------------*/
+@onyx-border-radius: 4px;
+@onyx-border-radius-tight: 3px;
+
+@onyx-button-border-radius: @onyx-border-radius-tight;
+@onyx-groupbox-border-radius: @onyx-border-radius;
+@onyx-input-border-radius: @onyx-border-radius-tight;
+@onyx-menu-border-radius: @onyx-border-radius-tight;
+@onyx-progressbar-border-radius: @onyx-border-radius-tight;
+@onyx-radiobutton-border-radius: @onyx-border-radius-tight;
+@onyx-togglebutton-border-radius: @onyx-border-radius-tight;
+@onyx-tooltip-border-radius: @onyx-border-radius-tight;
+
+/* Padding */
+/* ---------------------------------------*/
+@onyx-button-padding-lr: 18px;
+@onyx-button-padding-tb: 6px;
+@onyx-tabbutton-padding-lr: 34px;
+@onyx-tabbutton-padding-tb: 8px;
+
+/* Icon Sizes */
+/* ---------------------------------------*/
+@onyx-icon-size: 32px;
+
+/* Disabled Opacity */
+/* ---------------------------------------*/
+@onyx-disabled-opacity: 0.4;
+
+/* Gradient Overlays */
+/* ---------------------------------------*/
+@onyx-gradient: url(../images/gradient.png);
+@onyx-gradient-invert: url(../images/gradient-invert.png);
+
+@onyx-button-active-gradient: @onyx-gradient-invert;
+@onyx-button-gradient: @onyx-gradient;
+@onyx-groupbox-gradient: @onyx-gradient;
+@onyx-popup-gradient: @onyx-gradient;
+@onyx-progressbar-bar-gradient: @onyx-gradient;
+@onyx-progressbar-gradient: @onyx-gradient-invert;
+@onyx-radiobutton-active-gradient: @onyx-gradient-invert;
+@onyx-radiobutton-gradient: @onyx-gradient;
+@onyx-togglebutton-gradient: @onyx-gradient-invert;
+@onyx-togglebutton-knob-gradient: @onyx-gradient;
+@onyx-toolbar-gradient: @onyx-gradient;
+@onyx-tooltip-gradient: @onyx-gradient;
+
+/* Images */
+/* ---------------------------------------*/
+@onyx-checkbox-image: url(../images/checkbox.png);
+@onyx-checkbox-image-height: 32px;
+@onyx-checkbox-image-width: 32px;
+
+@onyx-grabber-image: url(../images/grabbutton.png);
+@onyx-grabber-image-height: 27px;
+@onyx-grabber-image-width: 23px;
+
+@onyx-more-toolbar-button-image: url(../images/more.png);
+@onyx-more-toolbar-button-image-height: 32px;
+@onyx-more-toolbar-button-image-width: 32px;
+
+@onyx-slider-knob-image: url(../images/slider-handle.png);
+@onyx-slider-knob-image-height: 40px;
+@onyx-slider-knob-image-width: 40px;
+
+@onyx-spinner-dark-image: url(../images/spinner-dark.gif);
+@onyx-spinner-light-image: url(../images/spinner-light.gif);
+@onyx-spinner-image-width: 59px;
+@onyx-spinner-image-height: 58px;
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssonyxcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/onyx.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/onyx.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/onyx.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,1153 @@
</span><ins>+/* WARNING: This is a generated file for backward-compatibility. Most */
+/* usrs should instead modify LESS files. If you choose to edit this CSS */
+/* directly rather than LESS files, you should make sure less.xx.yy.min.js */
+/* is commented out in your debug.html, and run deploy.sh/bat using the */
+/* '-c' flag to disable LESS compilation. This will force the loader and */
+/* minifier to fall back to using CSS files in place of the same-name */
+/* LESS file. */
+
+/* Onyx default parameters defined here */
+/* Fonts */
+/* ---------------------------------------*/
+/* Text Colors */
+/* ---------------------------------------*/
+/* Background Colors */
+/* ---------------------------------------*/
+/* Border Radius */
+/* ---------------------------------------*/
+/* Padding */
+/* ---------------------------------------*/
+/* Icon Sizes */
+/* ---------------------------------------*/
+/* Disabled Opacity */
+/* ---------------------------------------*/
+/* Gradient Overlays */
+/* ---------------------------------------*/
+/* Images */
+/* ---------------------------------------*/
+/* Onyx rules defined here */
+/* onyx-classes.less - combined CSS (less) files for all released Onyx controls
+ into single onyx.less file to avoid IE bug that allows
+ a maximum of 31 style sheets to be loaded before silently failing */
+.onyx {
+ color: #333333;
+ font-family: 'Helvetica Neue', 'Nimbus Sans L', Arial, sans-serif;
+ font-size: 20px;
+ cursor: default;
+ background-color: #eaeaea;
+ /* remove automatic tap highlight color */
+
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+/* prevent IE from inheriting line-height for these elements */
+.onyx button,
+.onyx label,
+.onyx input {
+ line-height: normal;
+}
+.onyx-selected {
+ background-color: #c4e3fe;
+}
+/* LESS pre-calculations */
+/* Individual Widget CSS */
+/* Icon.css */
+.onyx-icon,
+.onyx-icon-toggle {
+ width: 32px;
+ height: 32px;
+ background-repeat: no-repeat;
+ display: inline-block;
+ vertical-align: middle;
+}
+.onyx-icon.onyx-icon-button.active,
+.onyx-icon.onyx-icon-button.pressed,
+.onyx-icon.onyx-icon-button:active:hover,
+.onyx-icon-toggle.active {
+ background-position: 0 -32px;
+}
+.onyx-icon.disabled {
+ opacity: 0.4;
+ filter: alpha(opacity=40);
+}
+.onyx-icon.disabled:active:hover {
+ background-position: 0 0px;
+}
+/* Button.css */
+.onyx-button {
+ outline: 0;
+ color: #292929;
+ font-size: 16px;
+ text-align: center;
+ white-space: nowrap;
+ margin: 0;
+ padding: 6px 18px;
+ overflow: hidden;
+ border-radius: 3px;
+ /* for IE8 */
+
+ border: 1px solid #707070;
+ border: 1px solid rgba(15, 15, 15, 0.2);
+ /*
+ The border and the gradient interact in a strange way that
+ causes the bottom-border (top if the gradient is aligned top)
+ to be lighter than other borders.
+ We can fix it by using the darker bottom border below, but
+ then there are a few rogue pixels that end up very dark.
+ */
+
+ /* border-bottom: 1px solid rgba(15, 15, 15, 0.5); */
+
+ box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.2);
+ background: #e1e1e1 url(./../images/gradient.png) repeat-x bottom;
+ background-size: contain;
+ /**/
+
+ text-overflow: ellipsis;
+ /* the following cause arcane problems on IE */
+
+ /*
+ min-width: 14px;
+ min-height: 20px;
+ */
+
+}
+/*
+ IE8 can't handle these selectors in tandem:
+ .onyx-button.active, .onyx-button:active:not([disabled]) {
+
+ the effect is as if .onyx-button.active doesn't exist
+*/
+.onyx-button.active,
+.onyx-button.pressed {
+ background-image: url(./../images/gradient-invert.png);
+ background-position: top;
+ border-top: 1px solid rgba(15, 15, 15, 0.6);
+ box-shadow: inset 0px 1px 0px rgba(0, 0, 0, 0.1);
+}
+.onyx-button:active:hover:not([disabled]) {
+ background-image: url(./../images/gradient-invert.png);
+ background-position: top;
+ border-top: 1px solid rgba(15, 15, 15, 0.6);
+ box-shadow: inset 0px 1px 0px rgba(0, 0, 0, 0.1);
+}
+.onyx-button[disabled] {
+ opacity: 0.4;
+ filter: alpha(opacity=40);
+}
+.onyx-button > img {
+ padding: 0px 3px;
+}
+/* Remove the focused inner-border style in Firefox (Windows) */
+.onyx-button::-moz-focus-inner {
+ border: 0;
+}
+/* Checkbox.css */
+.onyx-checkbox {
+ cursor: pointer;
+ height: 32px;
+ width: 32px;
+ background: url(./../images/checkbox.png) no-repeat;
+ /* reset for ? */
+
+ margin: 0px;
+ /* these entries cause toggle-button and checkbox to line up properly*/
+
+ display: inline-block;
+ vertical-align: middle;
+}
+.onyx-checkbox[checked] {
+ background-position: 0px -32px;
+}
+.onyx-checkbox[disabled] {
+ opacity: 0.4;
+}
+/* Grabber.css */
+.onyx-grabber {
+ background: url(./../images/grabbutton.png) no-repeat center;
+ width: 23px;
+ height: 27px;
+}
+/* Popup.css */
+.onyx-popup {
+ font-size: 16px;
+ box-shadow: 0 6px 10px rgba(0, 0, 0, 0.2);
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 8px;
+ padding: 6px;
+ color: #ffffff;
+ background: #4c4c4c url(./../images/gradient.png) repeat-x 0 bottom;
+}
+.onyx-popup-decorator {
+ position: relative;
+}
+/* Groupbox.css */
+.onyx-groupbox > * {
+ display: block;
+ /*box-shadow: inset 0px 1px 1px rgba(255,255,255,0.5);*/
+
+ border-color: #aaaaaa;
+ border-style: solid;
+ border-width: 0 1px 1px 1px;
+ /*padding: 10px;*/
+
+ /* reset styles that make 'item' look bad if they happen to be there */
+
+ border-radius: 0;
+ margin: 0;
+ font-size: 16px;
+}
+.onyx-groupbox > *:first-child {
+ border-top-color: #aaaaaa;
+ border-width: 1px;
+ border-radius: 4px 4px 0 0;
+}
+.onyx-groupbox > *:last-child {
+ border-radius: 0 0 4px 4px;
+}
+.onyx-groupbox > *:first-child:last-child {
+ border-radius: 4px;
+}
+.onyx-groupbox-header {
+ padding: 2px 10px;
+ color: #ffffff;
+ font-size: 14px;
+ font-weight: bold;
+ text-transform: uppercase;
+ /**/
+
+ background-color: #4c4c4c;
+ border: none;
+ background: #4c4c4c url(./../images/gradient.png) repeat-x 0 10px;
+}
+.onyx-groupbox .onyx-input-decorator {
+ display: block;
+}
+.onyx-groupbox > .onyx-input-decorator {
+ border-color: #aaaaaa;
+ border-width: 0 1px 1px 1px;
+ border-radius: 0;
+}
+.onyx-groupbox > .onyx-input-decorator:first-child {
+ border-width: 1px;
+ border-radius: 4px 4px 0 0;
+}
+.onyx-groupbox > .onyx-input-decorator:last-child {
+ border-radius: 0 0 4px 4px;
+}
+.onyx-groupbox > .onyx-input-decorator:first-child:last-child {
+ border-radius: 4px;
+}
+/* Input.css */
+.onyx-input-decorator {
+ padding: 6px 8px 10px 8px;
+ border-radius: 3px;
+ border: 1px solid;
+ border-color: rgba(0, 0, 0, 0.1);
+ margin: 0;
+}
+.onyx-input-decorator.onyx-focused {
+ box-shadow: inset 0px 1px 4px rgba(0, 0, 0, 0.3);
+ border-color: rgba(0, 0, 0, 0.3);
+ background-color: #ffffff;
+}
+.onyx-input-decorator.onyx-disabled {
+ /* FIXME: needed to color a disabled input placeholder. */
+
+ /*-webkit-text-fill-color: #888;*/
+
+ opacity: 0.4;
+ filter: alpha(opacity=40);
+}
+.onyx-input-decorator > input {
+ /* reset */
+
+ margin: 0;
+ padding: 0;
+ border: none;
+ outline: none;
+ cursor: pointer;
+ background-color: transparent;
+ background-image: none;
+ font-size: 16px;
+ box-shadow: none;
+ /* FIXME: hack for styling reset on Android */
+
+ /* -webkit-appearance: caret;*/
+
+}
+.onyx-input-decorator.onyx-focused > input {
+ cursor: text;
+}
+.onyx-input-decorator.onyx-disabled > input {
+ cursor: default;
+}
+/* Menu.css */
+.onyx-menu,
+.onyx.onyx-menu {
+ min-width: 160px;
+ top: 100%;
+ left: 0;
+ margin-top: 2px;
+ padding: 3px 0;
+ border-radius: 3px;
+}
+.onyx-menu.onyx-menu-up {
+ top: auto;
+ bottom: 100%;
+ margin-top: 0;
+ margin-bottom: 2px;
+}
+.onyx-toolbar .onyx-menu {
+ margin-top: 11px;
+ border-radius: 0 0 3px 3px;
+}
+.onyx-toolbar .onyx-menu.onyx-menu-up {
+ margin-top: 0;
+ margin-bottom: 10px;
+ border-radius: 3px 3px 0 0;
+}
+.onyx-menu-item {
+ display: block;
+ padding: 10px;
+}
+.onyx-menu-item:hover {
+ background: #284152;
+}
+.onyx-menu-divider,
+.onyx-menu-divider:hover {
+ margin: 6px 0;
+ padding: 0;
+ border-bottom: 1px solid #aaa;
+}
+.onyx-menu-label {
+ cursor: default;
+ -webkit-user-select: none;
+ -moz-user-select: -moz-none;
+ user-select: none;
+ opacity: 0.4;
+ filter: alpha(opacity=40);
+}
+.onyx-menu-label:hover {
+ background: none;
+}
+/* customize a toolbar to support menus */
+.onyx-menu-toolbar,
+.onyx-toolbar.onyx-menu-toolbar {
+ position: relative;
+ z-index: 10;
+ overflow: visible;
+}
+/* Picker.css */
+.onyx-picker-decorator .onyx-button {
+ padding: 10px 18px;
+}
+.onyx-picker {
+ top: 0;
+ margin-top: -3px;
+ min-width: 0;
+ width: 100%;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ color: black;
+ background: #e1e1e1;
+}
+.onyx-picker.onyx-menu-up {
+ top: auto;
+ bottom: 0;
+ margin-top: 3px;
+ margin-bottom: -3px;
+}
+.onyx-picker .onyx-menu-item {
+ text-align: center;
+}
+.onyx-picker .onyx-menu-item:hover {
+ background-color: transparent;
+}
+.onyx-picker .onyx-menu-item.selected,
+.onyx-picker .onyx-menu-item.active,
+.onyx-picker .onyx-menu-item:active:hover {
+ border-top: 1px solid rgba(0, 0, 0, 0.1);
+ background-color: #cde7fe;
+ box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.2);
+}
+.onyx-picker .onyx-menu-item {
+ border-top: 1px solid rgba(255, 255, 255, 0.5);
+ border-bottom: 1px solid rgba(0, 0, 0, 0.2);
+}
+.onyx-picker:not(.onyx-flyweight-picker) .onyx-menu-item:first-child,
+.onyx-flyweight-picker :first-child > .onyx-menu-item {
+ border-top: none;
+}
+.onyx-picker:not(.onyx-flyweight-picker) .onyx-menu-item:last-child,
+.onyx-flyweight-picker :last-child > .onyx-menu-item {
+ border-bottom: none;
+}
+/* TextArea.css */
+.onyx-input-decorator > textarea {
+ /* reset */
+
+ margin: 0;
+ padding: 0;
+ border: none;
+ outline: none;
+ cursor: pointer;
+ background-color: transparent;
+ background-image: none;
+ font-size: 16px;
+ box-shadow: none;
+ /* Remove scrollbars and resize handle */
+
+ resize: none;
+ overflow: auto;
+ /* FIXME: hack for styling reset on Android */
+
+ /* -webkit-appearance: caret;*/
+
+}
+.onyx-input-decorator.onyx-focused > textarea {
+ cursor: text;
+}
+.onyx-input-decorator.onyx-disabled > textarea {
+ cursor: default;
+}
+.onyx-textarea {
+ /* need >=50px for scrollbar to be usable on mac */
+
+ min-height: 50px;
+}
+/* RichText.css */
+.onyx-input-decorator > .onyx-richtext {
+ /* reset */
+
+ margin: 0;
+ padding: 0;
+ border: none;
+ outline: none;
+ cursor: pointer;
+ background-color: transparent;
+ background-image: none;
+ font-size: 16px;
+ min-height: 20px;
+ min-width: 100px;
+ box-shadow: none;
+ /* FIXME: hack for styling reset on Android */
+
+ /* -webkit-appearance: caret;*/
+
+}
+.onyx-input-decorator.onyx-focused > .onyx-richtext {
+ cursor: text;
+}
+.onyx-input-decorator.onyx-disabled > .onyx-richtext {
+ cursor: default;
+}
+/* RadioButton.css */
+.onyx-radiobutton {
+ padding: 8px 12px;
+ margin: 0;
+ outline: 0;
+ font-size: 16px;
+ text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
+ text-align: center;
+ /**/
+
+ background: #e7e7e7 url(./../images/gradient.png) repeat-x bottom;
+ /* IE8 */
+
+ border: 1px solid #333333;
+ border: 1px solid rgba(15, 15, 15, 0.2);
+ /* turn off right-border in a way IE8 ignores, because IE8 does not support :last-child */
+
+ border-right-color: rgba(0, 0, 0, 0);
+ box-shadow: inset 1px 1px 0px rgba(255, 255, 255, 0.2);
+}
+.onyx-radiobutton:first-child {
+ border-radius: 3px 0 0 3px;
+}
+.onyx-radiobutton:last-child {
+ border-radius: 0px 3px 3px 0px;
+ /* IE8 */
+
+ border-right: 1px solid #333333;
+ border-right: 1px solid rgba(15, 15, 15, 0.2);
+}
+.onyx-radiobutton.active {
+ color: #ffffff;
+ background: #0091f2 url(./../images/gradient-invert.png) repeat-x top;
+ border-top: 1px solid rgba(15, 15, 15, 0.6);
+ box-shadow: inset 1px 2px 2px rgba(0, 0, 0, 0.2);
+}
+/* Scrim.css */
+.onyx-scrim {
+ z-index: 1;
+ /*
+ note: by using pointer-events we allow tapping on scrim
+ while it is fading out; however, this requires any showing classes
+ to set pointer events to auto or scrim will not function as expected.
+ */
+
+ pointer-events: none;
+}
+.onyx-scrim.onyx-scrim-translucent {
+ pointer-events: auto;
+ background-color: #000000;
+ opacity: 0.65;
+ filter: alpha(opacity=65);
+}
+.onyx-scrim.onyx-scrim-transparent {
+ pointer-events: auto;
+ background: transparent;
+}
+/* TabButton.css */
+.onyx-radiobutton.onyx-tabbutton {
+ padding: 8px 34px;
+ font-size: 20px;
+ border-radius: 0px;
+}
+/* ToggleButton.css */
+.onyx-toggle-button {
+ display: inline-block;
+ height: 32px;
+ line-height: 32px;
+ min-width: 64px;
+ vertical-align: middle;
+ text-align: center;
+ /* */
+
+ border-radius: 3px;
+ box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.4);
+ background: #8bba3d url(./../images/gradient-invert.png) repeat-x bottom;
+ background-size: auto 100%;
+ /* label */
+
+ color: #ffffff;
+ font-size: 14px;
+ font-weight: bold;
+ text-transform: uppercase;
+}
+.onyx-toggle-button.off {
+ background-color: #b1b1b1 !important;
+}
+.onyx-toggle-button-knob {
+ display: inline-block;
+ width: 30px;
+ height: 30px;
+ margin: 1px;
+ border-radius: 3px;
+ background: #f6f6f6 url(./../images/gradient.png) repeat-x;
+ background-size: auto 100%;
+}
+.onyx-toggle-button .onyx-toggle-button-knob {
+ box-shadow: -1px 0px 4px rgba(0, 0, 0, 0.35), inset 0 -1px 0 rgba(0, 0, 0, 0.4);
+ float: right;
+}
+.onyx-toggle-button.off .onyx-toggle-button-knob {
+ box-shadow: 1px 0px 4px rgba(0, 0, 0, 0.35), inset 0 -1px 0 rgba(0, 0, 0, 0.4);
+ float: left;
+}
+.onyx-toggle-button.disabled,
+.onyx-icon-button.disabled {
+ opacity: 0.4;
+ filter: alpha(opacity=40);
+}
+.onyx-toggle-content {
+ min-width: 32px;
+ padding: 0 6px;
+}
+.onyx-toggle-content.empty {
+ padding: 0;
+}
+.onyx-toggle-content.off {
+ float: right;
+}
+.onyx-toggle-content.on {
+ float: left;
+}
+/* Toolbar.css */
+.onyx-toolbar {
+ /*
+ line-height is unreliable for centering, instead
+ use vertical-align: middle to align
+ elements along a common centerline and use
+ padding to fill out the space.
+ */
+
+ padding: 9px 8px 10px 8px;
+ border: 1px solid #3A3A3A;
+ background: #4c4c4c url(./../images/gradient.png) repeat-x 0 bottom;
+ background-size: contain;
+ color: #ffffff;
+ /**/
+
+ white-space: nowrap;
+ overflow-y: visible;
+ font-size: 20px;
+}
+.onyx-toolbar-inline > *,
+.enyo-fittable-columns-layout.onyx-toolbar-inline > * {
+ display: inline-block;
+ vertical-align: middle;
+ margin: 4px 6px 5px;
+ box-sizing: border-box;
+}
+.onyx-toolbar .onyx-icon-button {
+ margin: 3px 2px 1px;
+}
+.onyx-toolbar .onyx-button {
+ color: #f2f2f2;
+ background-color: #555656;
+ border-color: rgba(15, 15, 15, 0.5);
+ margin-top: 0;
+ margin-bottom: 0;
+ height: 36px;
+}
+.onyx-toolbar .onyx-input-decorator {
+ margin: 1px 3px;
+ box-shadow: inset 0px 1px 4px rgba(0, 0, 0, 0.1);
+ background-color: rgba(0, 0, 0, 0.1);
+ padding: 0px 6px 5px 6px;
+}
+.onyx-toolbar .onyx-input-decorator.onyx-focused {
+ box-shadow: inset 0px 1px 4px rgba(0, 0, 0, 0.3);
+ background-color: #ffffff;
+}
+.onyx-toolbar .onyx-input-decorator .onyx-input {
+ color: #e5e5e5;
+ font-size: 14px;
+}
+.onyx-toolbar .onyx-input-decorator .onyx-input:focus {
+ color: #000000;
+}
+.onyx-toolbar .onyx-input-decorator .onyx-input:focus::-webkit-input-placeholder {
+ color: #dddddd;
+}
+/* Tooltip.css */
+.onyx-tooltip {
+ z-index: 20;
+ left: 0;
+ padding: 4px 6px;
+ margin-top: 4px;
+ margin-left: -6px;
+ box-shadow: 0 6px 10px rgba(0, 0, 0, 0.2);
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ color: #ffffff;
+ background: #216593 url(./../images/gradient.png) repeat-x 0 bottom;
+ border-radius: 3px;
+ white-space: nowrap;
+}
+/*move the tooltip over to the right when displaying the right arrow so it aligns better with the decorator*/
+.onyx-tooltip.right-arrow {
+ left: 30px;
+}
+/*prep the left & right arrows using before & after - left arrow uses before & right arrow uses after*/
+.onyx-tooltip::before {
+ content: '';
+ border-left: 6px solid transparent;
+ border-right: 6px solid transparent;
+ position: absolute;
+ top: -6px;
+ left: 16px;
+}
+.onyx-tooltip::after {
+ content: '';
+ border-left: 6px solid transparent;
+ border-right: 6px solid transparent;
+ position: absolute;
+ top: -6px;
+ margin-left: -12px;
+}
+/*The following 3 rules handle the left & right arrows when the tooltip is displayed below the activator*/
+.onyx-tooltip.below {
+ top: 100%;
+}
+.onyx-tooltip.below.right-arrow::after {
+ border-bottom: 6px solid #1D587F;
+ top: -6px;
+}
+.onyx-tooltip.below.left-arrow::before {
+ border-bottom: 6px solid #1D587F;
+ top: -6px;
+}
+/*The following 3 rules handle the left & right arrows when the tooltip is displayed above the activator*/
+.onyx-tooltip.above {
+ top: -100%;
+}
+.onyx-tooltip.above.right-arrow::after {
+ content: '';
+ border-top: 6px solid #1D587F;
+ top: 100%;
+}
+.onyx-tooltip.above.left-arrow::before {
+ content: '';
+ border-top: 6px solid #1D587F;
+ top: 100%;
+}
+/* ProgressBar.css */
+.onyx-progress-bar {
+ margin: 8px;
+ height: 8px;
+ border: 1px solid rgba(15, 15, 15, 0.2);
+ border-radius: 3px;
+ background: #b8b8b8 url(./../images/gradient-invert.png) repeat-x;
+ background-size: auto 100%;
+}
+.onyx-progress-bar-bar {
+ height: 100%;
+ border-radius: 3px;
+ background: #58abef url(./../images/gradient.png) repeat-x;
+ background-size: auto 100%;
+}
+.onyx-progress-bar-bar.striped {
+ background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-size: 40px 40px;
+}
+.onyx-progress-bar-bar.striped.animated {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -moz-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 0 0;
+ }
+ to {
+ background-position: 40px 0;
+ }
+}
+@-moz-keyframes progress-bar-stripes {
+ from {
+ background-position: 0 0;
+ }
+ to {
+ background-position: 40px 0;
+ }
+}
+@-o-keyframes progress-bar-stripes {
+ from {
+ background-position: 0 0;
+ }
+ to {
+ background-position: 40px 0;
+ }
+}
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 0 0;
+ }
+ to {
+ background-position: 40px 0;
+ }
+}
+/* ProgressButton.css */
+.onyx-progress-button {
+ position: relative;
+ height: 36px;
+ line-height: 36px;
+ color: #f1f1f1;
+ font-size: 16px;
+ text-overflow: ellipsis;
+}
+.onyx-progress-button-bar {
+ height: 36px;
+}
+.onyx-progress-button-icon {
+ display: inline-block;
+ position: absolute;
+ top: 2px;
+ right: 0;
+}
+.onyx-progress-button-client {
+ display: inline-block;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 36px;
+ margin-left: 8px;
+}
+.onyx-progress-button-client > * {
+ display: inline-block;
+}
+/* Slider.css */
+.onyx-slider {
+ position: relative;
+ margin: 8px 20px;
+}
+.onyx-slider-taparea {
+ position: absolute;
+ top: -11px;
+ height: 28px;
+ width: 100%;
+}
+.onyx-slider-knob {
+ position: relative;
+ height: 40px;
+ width: 40px;
+ background: url(./../images/slider-handle.png) left top no-repeat;
+ margin: -23px -20px;
+}
+.onyx-slider-knob.active,
+.onyx-slider-knob.pressed,
+.onyx-slider-knob:active:hover {
+ background-position: 0 -40px;
+}
+/* RangeSlider.css */
+.onyx-range-slider-knob {
+ top: -17px;
+}
+.onyx-range-slider-label {
+ position: relative;
+ top: -18px;
+ text-align: center;
+ white-space: nowrap;
+}
+/* Item.css */
+.onyx-item {
+ padding: 14px;
+}
+.onyx-highlight,
+.onyx-highlight.onyx-swipeable-item-content {
+ background-color: #dedfdf;
+}
+.enyo-selected,
+.enyo-selected.onyx-swipeable-item-content {
+ background-color: #c4e3fe;
+}
+.onyx-item.onyx-swipeable-item {
+ overflow: hidden;
+ padding: 0;
+}
+.onyx-swipeable-item-content {
+ background-color: #eaeaea;
+ box-sizing: border-box;
+ padding: 18px 6px;
+ min-height: 40px;
+}
+/* Spinner.css */
+.onyx-spinner {
+ width: 59px;
+ height: 58px;
+ display: inline-block;
+ background: url(./../images/spinner-dark.gif) no-repeat 0 0;
+}
+.onyx-spinner.onyx-light {
+ background: url(./../images/spinner-light.gif) no-repeat 0 0;
+}
+/* MoreToolbar.css */
+.onyx-more-toolbar {
+ overflow: visible;
+ position: relative;
+ z-index: 10;
+}
+.onyx-more-toolbar.active {
+ z-index: 11;
+}
+.onyx-more-menu {
+ left: auto;
+ right: 0px;
+ min-width: 0;
+}
+.onyx-more-toolbar .onyx-more-menu > * {
+ float: right;
+ clear: both;
+ margin: 5px;
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+.onyx-more-button {
+ background-image: url(./../images/more.png);
+ width: 32px;
+ height: 32px;
+}
+/* DatePicker.css */
+.onyx-datepicker-month {
+ min-width: 75px;
+}
+.onyx-datepicker-day {
+ min-width: 60px;
+}
+.onyx-datepicker-year {
+ min-width: 70px;
+}
+/* TimePicker.css */
+.onyx-timepicker-hour {
+ min-width: 60px;
+}
+.onyx-timepicker-minute {
+ min-width: 60px;
+}
+.onyx-timepicker-ampm {
+ min-width: 60px;
+}
+/* ButtonColors.css */
+.onyx-button.onyx-blue {
+ background-color: #35A8EE;
+ color: #F2F2F2;
+}
+.onyx-button.onyx-affirmative {
+ background-color: #91BA07;
+ color: #F2F2F2;
+}
+.onyx-button.onyx-negative {
+ background-color: #C51616;
+ color: #F2F2F2;
+}
+.onyx-button.onyx-dark {
+ background-color: #555656;
+ color: #F2F2F2;
+}
+.onyx-button.onyx-light {
+ background-color: #cacaca;
+ color: #2F2F2F;
+}
+/* ContextualPopup.css */
+.onyx-contextual-popup-title {
+ font-weight: bold;
+ padding: 24px 32px 0px;
+}
+.onyx-contextual-popup-scroller {
+ padding: 24px 32px;
+}
+.onyx-contextual-popup-action-buttons {
+ display: inline-block;
+ width: 100%;
+ text-align: center;
+}
+.onyx-contextual-popup-action-button {
+ margin-left: 5px;
+ margin-right: 5px;
+}
+.onyx-contextual-popup,
+.onyx.onyx-contextual-popup {
+ font-size: 16px;
+ box-shadow: 0 6px 10px rgba(0, 0, 0, 0.2);
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 8px;
+ padding: 6px;
+ color: #ffffff;
+ background: #4c4c4c;
+}
+/*setup the nub*/
+.onyx-contextual-popup::after {
+ content: '';
+ position: absolute;
+ top: -10px;
+ border-left: 10px solid transparent;
+ border-right: 10px solid transparent;
+ border-top: 10px solid transparent;
+ border-bottom: 10px solid transparent;
+}
+/*for popups above activator*/
+.onyx-contextual-popup.vertical.above {
+ top: auto;
+ margin-top: -10px;
+ bottom: 100%;
+ margin-bottom: 10px;
+}
+/*for popups below activator*/
+.onyx-contextual-popup.vertical.below {
+ margin-top: 10px;
+}
+/*for popups on the left of the activator*/
+.onyx-contextual-popup.right.horizontal {
+ margin-left: -11px;
+}
+/*for popups on the right of the activator*/
+.onyx-contextual-popup.left.horizontal {
+ margin-left: 10px;
+}
+/*nub positioning*/
+/*horizontally centered nub*/
+.onyx-contextual-popup.vertical::after {
+ position: absolute;
+ left: 45%;
+ border-bottom: 10px solid #4c4c4c;
+ border-top: none;
+ border-left: 10px solid transparent;
+ border-right: 10px solid transparent;
+}
+/*nub near horizontal left*/
+.onyx-contextual-popup.vertical.right::after {
+ left: 0%;
+ margin-left: 20px;
+}
+/*nub near horizontal right*/
+.onyx-contextual-popup.vertical.left::after {
+ left: 100%;
+ margin-left: -55px;
+}
+/*downward facing nub*/
+.onyx-contextual-popup.vertical.above::after {
+ top: 100%;
+ border-top: 10px solid #4c4c4c;
+ border-bottom: none;
+ border-left: 10px solid transparent;
+ border-right: 10px solid transparent;
+}
+.onyx-contextual-popup.vertical.below.right::after {
+ top: 0%;
+ margin-top: -10px;
+ border-bottom: 10px solid #4c4c4c;
+ border-left: 10px solid transparent;
+}
+.onyx-contextual-popup.vertical.below.left::after {
+ top: 0%;
+ margin-top: -10px;
+ border-right: 10px solid transparent;
+}
+/*nub positioning for left/right popups*/
+/*vertically centered nub for popups on left of activator*/
+.onyx-contextual-popup.right::after {
+ left: 100%;
+ top: 47%;
+ margin-right: 20px;
+ border-left: 10px solid #4C4C4C;
+}
+/*nub near vertical top for popups on left of activator*/
+.onyx-contextual-popup.right.high::after {
+ top: 35px;
+ border-left: 10px solid #4C4C4C;
+}
+/*nub near vertical bottom for popups on left of activator*/
+.onyx-contextual-popup.right.low::after {
+ top: 100%;
+ margin-top: -55px;
+ border-left: 10px solid #4C4C4C;
+}
+/*vertically centered nub for popups on right of activator*/
+.onyx-contextual-popup.left::after {
+ left: 0%;
+ margin-left: -20px;
+ top: 45%;
+ border-right: 10px solid #4C4C4C;
+}
+/*nub near vertical top for popups on right of activator*/
+.onyx-contextual-popup.left.high::after {
+ top: 35px;
+ border-right: 10px solid #4C4C4C;
+}
+/*nub near vertical bottom for popups on right of activator*/
+.onyx-contextual-popup.left.low::after {
+ top: 100%;
+ margin-top: -55px;
+ border-right: 10px solid #4C4C4C;
+}
+/*corners*/
+/*vertical top corners*/
+/*for popups on the left of the activator*/
+.onyx-contextual-popup.vertical.right.corner {
+ margin-left: 0px;
+}
+/*for popups on the right of the activator*/
+.onyx-contextual-popup.vertical.left.corner {
+ margin-left: 0px;
+}
+.onyx-contextual-popup.vertical.below.left.corner {
+ border-top-right-radius: 0px;
+}
+.onyx-contextual-popup.vertical.below.right.corner {
+ border-top-left-radius: 0px;
+}
+.onyx-contextual-popup.vertical.below.left.corner::after {
+ top: 0%;
+ left: 100%;
+ margin-top: -10px;
+ margin-left: -19px;
+ border-right: 10px solid #4c4c4c;
+ border-top: 10px solid transparent;
+}
+.onyx-contextual-popup.vertical.below.right.corner::after {
+ top: 0%;
+ left: 0%;
+ margin-left: -1px;
+ border-left: 10px solid #4c4c4c;
+ border-top: 10px solid transparent;
+}
+/*vertical bottom corners*/
+.onyx-contextual-popup.left.above.corner {
+ border-bottom-right-radius: 0px;
+}
+.onyx-contextual-popup.right.above.corner {
+ border-bottom-left-radius: 0px;
+}
+.onyx-contextual-popup.vertical.left.above.corner::after {
+ top: 100%;
+ margin-left: -19px;
+ border-right: 10px solid #4C4C4C;
+ border-bottom: 10px solid transparent;
+ border-top: none;
+}
+.onyx-contextual-popup.vertical.right.above.corner::after {
+ top: 100%;
+ left: 0%;
+ margin-left: -1px;
+ border-left: 10px solid #4c4c4c;
+ border-bottom: 10px solid transparent;
+ border-top: none;
+}
+/*horizontal bottom corners*/
+.onyx-contextual-popup.left.low.corner {
+ border-bottom-left-radius: 0px;
+}
+.onyx-contextual-popup.right.low.corner {
+ border-bottom-right-radius: 0px;
+}
+.onyx-contextual-popup.left.low.corner::after {
+ top: 100%;
+ left: 0%;
+ margin-top: -19px;
+ margin-left: -12px;
+ border-bottom: 10px solid #4c4c4c;
+ border-right: 10px solid #4c4c4c;
+}
+.onyx-contextual-popup.right.low.corner::after {
+ top: 100%;
+ left: 100%;
+ margin-top: -19px;
+ border-bottom: 10px solid#4c4c4c;
+ border-left: none;
+}
+/*horizontal top corners*/
+.onyx-contextual-popup.left.high.corner {
+ border-top-left-radius: 0px;
+}
+.onyx-contextual-popup.right.high.corner {
+ border-top-right-radius: 0px;
+}
+.onyx-contextual-popup.left.high.corner::after {
+ top: 0%;
+ left: 0%;
+ margin-top: -1px;
+ margin-left: -12px;
+ border-top: 10px solid #4C4C4C;
+ border-bottom: none;
+}
+.onyx-contextual-popup.right.high.corner::after {
+ top: 0%;
+ left: 100%;
+ margin-top: -1px;
+ margin-left: -9px;
+ border-top: 10px solid #4C4C4C;
+ border-bottom: none;
+}
+/* some default colors */
+.onyx-dark {
+ background-color: #555656;
+}
+.onyx-light {
+ background-color: #cacaca;
+}
+.onyx-green {
+ background-color: #91BA07;
+}
+.onyx-red {
+ background-color: #C51616;
+}
+.onyx-blue {
+ background-color: #35A8EE;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcssonyxless"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/onyx.less (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/onyx.less (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/onyx.less 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+/* Onyx default parameters defined here */
+@import "onyx-variables.less";
+
+/* Onyx rules defined here */
+@import "onyx-rules.less";
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxcsspackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/css/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/css/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/css/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+enyo.depends(
+ "onyx.less"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxdeploybat"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/deploy.bat (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/deploy.bat (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/deploy.bat 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+@ECHO OFF
+
+REM make sure we don't stomp variables in calling script
+SETLOCAL
+
+REM the location of this batch file
+SET SOURCE="%~dp0"
+
+REM target location
+SET TARGET=%1
+
+IF [%TARGET%]==[] GOTO FAIL
+
+GOTO OK
+
+:FAIL
+
+ECHO Must supply target folder parameter, e.g.:
+ECHO.
+ECHO deploy.bat ../deploy/lib/onyx
+ECHO.
+GOTO :EOF
+
+:OK
+
+REM copy assets
+XCOPY %SOURCE%images\*.* %TARGET%\images\ /Q /E
+
+REM copy root folder files
+COPY %SOURCE%*.txt %TARGET%\ >NUL
+
+ENDLOCAL
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxdeploysh"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/deploy.sh (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/deploy.sh (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/deploy.sh 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+#!/bin/bash
+
+SOURCE=$(cd `dirname $0`; pwd)
+
+# target location
+TARGET=$1
+
+if [ x$TARGET = x ]; then
+
+cat <<EOF
+Must supply target folder parameter, e.g.:
+
+ deploy.bat ../deploy/lib/onyx
+EOF
+else
+ mkdir -p $TARGET/images/
+ cp -r $SOURCE/images/*.* $TARGET/images/
+ cp -r $SOURCE/*.txt $TARGET
+fi
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/deploy.sh
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyxdesigninlinecontrolledhtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/design/inline-controlled.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/design/inline-controlled.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/design/inline-controlled.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,231 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>controlled inline: onyx toolbar design</title>
+ <link href="../source/css/onyx.css" rel="stylesheet" type="text/css" />
+ <style>
+ /*
+ the 'inline' class sets up a left-to-right container, with vertically centered children
+ */
+ .inline {
+ white-space: nowrap;
+ }
+ .inline > * {
+ display: inline-block;
+ vertical-align: middle;
+ }
+ .icon {
+ width: 32px;
+ height: 32px;
+ background-image: url(menu-icon-bookmark.png);
+ }
+ .bord {
+ border: 1px solid lightblue;
+ }
+ .big {
+ font-size: 48px;
+ }
+ .pad {
+ padding: 8px;
+ }
+ .bg {
+ background: orange;
+ }
+ /*
+ We can control line-height so that vertical-align: middle
+ becomes true center. Otherwise, when line-height is in effect
+ (i.e. if the actual height is less than line height),
+ user agents pad the line unevenly.
+ */
+ .lhc {
+ line-height: 0;
+ }
+ /*
+ Defeat line-height control above for children
+ */
+ .lhc > * {
+ line-height: normal;
+ }
+ /*
+ Enforce line-height 0 for an inline child of an inline (FIXME: fiddly)
+ */
+ .lhc .lhc {
+ line-height: 0px;
+ }
+ /**/
+ .h {
+ height: 64px;
+ }
+ /*
+ It's useful to be able to abut toolbars in an inline context
+ and not worry about varying heights.
+ Generally icons are the largest elements in a toolbar, and will
+ drive the height to this size.
+ We can't set a min-size directly on the toolbar because it
+ breaks centering (due to interation with line-height).
+ For some scenarios a developer may want to override the height value.
+ */
+ .stent {
+ /*
+ the point of the stent is to force the box height to some minimum, similar
+ to line-height, but with proper vertical centering
+ */
+ height: 72px;
+ /* the width is 0, but it adds some size to the inline because of ? */
+ width: 0px;
+ visibility: hidden;
+ }
+ .stent-fix {
+ /* stent imparts mystery width to it's parent */
+ /* setting font-size doesn't affect the mystery width */
+ /*font-size: 0px;*/
+ /* floating the stent prevents it from stenting */
+ /*float: left;*/
+ /* on non-mozilla, mystery size can be removed this way, but the actual pixels needed depends on font size */
+ /*margin-right: -6px;*/
+ /* on non-mozilla, this gets us within a few pixels for tested fonts */
+ margin-right: -0.25em;
+ }
+ /* */
+ .stenty > * {
+ min-height: 56px;
+ }
+ </style>
+</head>
+<body>
+ <label>"inline" tests</label>
+ <br /><br />
+
+ <div>
+ <label>combo content: when the text is larger than non-text objects, vertical centering goes wonky</label>
+ <div class="inline bord big">
+ <div>Text in Div</div>
+ <input />
+ <div class="icon"></div>
+ </div>
+ <br />
+
+ <label>... it's possible to control line-height in such a way to repair centering</label>
+ <div class="inline bord big lhc">
+ <div>Text in Div</div>
+ <input />
+ <div class="icon"></div>
+ </div>
+ <br />
+
+ <hr />
+
+ <label>but now setting height or min-height on toolbar breaks centering</label>
+ <div class="inline bord lhc bg big h">
+ <div>Text in Div</div>
+ <input />
+ <div class="icon"></div>
+ </div>
+ <br />
+
+ <div class="inline bord big lhc">
+ <div class="inline bord lhc bg h">
+ <div>Text in Div</div>
+ <input />
+ <div class="icon"></div>
+ </div>
+ <div class="inline bord lhc bg h">
+ <input />
+ <div class="icon"></div>
+ </div>
+ </div>
+ <br />
+
+ <hr />
+
+ <label>control height on children instead of toolbar</label>
+ <div class="inline bord big lhc">
+ <div class="inline bord lhc bg">
+ <div>Text in Div</div>
+ <input />
+ <div class="icon"></div>
+ </div>
+ <div class="inline bord lhc bg">
+ <input />
+ <div class="icon"></div>
+ </div>
+ </div>
+ <br />
+ <div class="inline bord big lhc">
+ <div class="inline bord lhc bg stenty">
+ <div>Text in Div</div>
+ <input />
+ <div class="icon"></div>
+ </div>
+ <div class="inline bord lhc bg stenty">
+ <input />
+ <div class="icon"></div>
+ </div>
+ </div>
+ <br />
+
+ <hr />
+
+ <label>it's possible to use a stent to effect min-height, but for unknown reasons, even a 0-width stent affects parent width</label>
+ <div class="inline bord big lhc">
+ <div class="inline bord lhc bg">
+ <div>Text in Div</div>
+ <input />
+ <div class="icon"></div>
+ </div>
+ <div class="inline bord lhc bg">
+ <input />
+ <div class="icon"></div>
+ </div>
+ </div>
+ <br />
+ <div class="inline bord big lhc">
+ <div class="inline bord lhc bg">
+ <div class="stent"></div>
+ <div>Text in Div</div>
+ <input />
+ <div class="icon"></div>
+ </div>
+ <div class="inline bord lhc bg">
+ <div class="stent"></div>
+ <input />
+ <div class="icon"></div>
+ </div>
+ </div>
+ <br />
+
+ <label>using img as stent node makes no difference</label>
+ <div class="inline bord big lhc">
+ <div class="inline bord lhc bg">
+ <img class="stent" />
+ <div>Text in Div</div>
+ <input />
+ <div class="icon"></div>
+ </div>
+ <div class="inline bord lhc bg">
+ <img class="stent" />
+ <input />
+ <div class="icon"></div>
+ </div>
+ </div>
+ <br />
+
+ <label>using negative margin on stent can approximate 0 width</label>
+ <div class="inline bord big lhc">
+ <div class="inline bord lhc bg">
+ <div class="stent stent-fix"></div>
+ <div>Text in Div</div>
+ <input />
+ <div class="icon"></div>
+ </div>
+ <div class="inline bord lhc bg">
+ <div class="stent stent-fix"></div>
+ <input />
+ <div class="icon"></div>
+ </div>
+ </div>
+ <br />
+ </div>
+</body>
+</html>
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxdesigninlinehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/design/inline.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/design/inline.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/design/inline.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,103 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>inline: onyx toolbar design</title>
+ <link href="../source/css/onyx.css" rel="stylesheet" type="text/css" />
+ <style>
+ /*
+ the 'inline' class sets up a left-to-right container, with vertically centered children
+ */
+ .inline {
+ white-space: nowrap;
+ }
+ .inline > * {
+ display: inline-block;
+ vertical-align: middle;
+ }
+ .icon {
+ width: 32px;
+ height: 32px;
+ background-image: url(menu-icon-bookmark.png);
+ }
+ .bord {
+ border: 1px solid lightblue;
+ }
+ .big {
+ font-size: 48px;
+ }
+ .pad {
+ padding: 8px;
+ }
+ .mh {
+ min-height: 124px;
+ }
+ .lh {
+ line-height: 86px;
+ }
+ </style>
+</head>
+<body>
+ <label>"inline" tests</label>
+ <br /><br />
+ <div>
+ <label>no content</label>
+ <div class="inline bord"></div>
+ <br />
+
+ <label>text only content</label>
+ <div class="inline bord">Text</div>
+ <br />
+
+ <label>div content</label>
+ <div class="inline bord">
+ <div>Text in Div</div>
+ </div>
+ <br />
+
+ <label>input content</label>
+ <div class="inline bord">
+ <input class="" />
+ </div>
+ <br />
+
+ <label>icon content</label>
+ <div class="inline bord">
+ <div class="icon"></div>
+ </div>
+ <br />
+
+ <label>combo content</label>
+ <div class="inline bord">
+ <div>Text in Div</div>
+ <input class="" />
+ <div class="icon"></div>
+ </div>
+ <br />
+
+ <label>combo content: when the text is larger than non-text objects, vertical centering goes wonky</label>
+ <div class="inline bord big">
+ <div>Text in Div</div>
+ <input class="" />
+ <div class="icon"></div>
+ </div>
+ <br />
+
+ <label>controlling height</label>
+ <div class="inline bord big mh">
+ <div>Text in Div</div>
+ <input class="" />
+ <div class="icon"></div>
+ </div>
+ <br />
+
+ <label>controlling line-height</label>
+ <div class="inline bord big lh pad">
+ <div>Text in Div</div>
+ <input class="" />
+ <div class="icon"></div>
+ </div>
+ <br />
+ </div>
+</body>
+</html>
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxdesignmenuiconbookmarkpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/design/menu-icon-bookmark.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/design/menu-icon-bookmark.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/design/menu-icon-bookmark.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/design/menu-icon-bookmark.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/design/menu-icon-bookmark.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyxdesigntoolbarextendedhtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/design/toolbar-extended.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/design/toolbar-extended.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/design/toolbar-extended.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,243 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>onyx toolbar design</title>
+ <link href="../source/css/onyx.css" rel="stylesheet" type="text/css" />
+ <style>
+ /*
+ the 'inline' class attempts to setup a left-to-right container, with vertically centered children
+ */
+ .toolbar > *, .inline > * {
+ display: inline-block;
+ vertical-align: middle;
+ }
+ .toolbar, .inline {
+ white-space: nowrap;
+ /*
+ We want to control line-height so that vertical-align: middle
+ becomes true center. Otherwise, when line-height is in effect
+ (i.e. if the actual height is less than line height),
+ user agents pad the line unevenly.
+ */
+ line-height: 0;
+ }
+ .toolbar > *, .inline > * {
+ /*
+ Defeat line-height control above for children
+ */
+ line-height: normal;
+ }
+ .toolbar .inline, .inline .inline {
+ /*
+ Enforce line-height 0 for an inline child of an inline (FIXME: fiddly)
+ */
+ line-height: 0px;
+ }
+ /*
+ toolbar is just an inline context with specific styling
+ */
+ .toolbar {
+ padding: 8px;
+ /**/
+ box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -ms-box-sizing: border-box;
+ }
+ /*
+ It's useful to be able to abut toolbars in an inline context
+ and not worry about varying heights.
+ Generally icons are the largest elements in a toolbar, and will
+ drive the height to this size.
+ We can't set a min-size directly on the toolbar because it
+ breaks centering (due to interation with line-height).
+ For some scenarios a developer may want to override the height value.
+ */
+ .stent {
+ visibility: none;
+ width: 0px;
+ height: 34px;
+ }
+ /* */
+ .onyx .toolbar {
+ padding: 8px;
+ /**/
+ border: 1px solid #3A3A3A;
+ background: #4C4C4C url(../images/gradient.png) repeat-x 0 bottom;
+ color: white;
+ }
+ /* */
+ button {
+ /* only needed for IE */
+ line-height: normal !important;
+ }
+ .icon {
+ width: 32px;
+ height: 32px;
+ background-image: url(menu-icon-bookmark.png);
+ }
+ /* */
+ /*
+ for display/debug only, not part of the design
+ */
+ .big {
+ font-size: 42px;
+ }
+ .bord {
+ border: 1px solid lightblue;
+ }
+ .bg {
+ background-color: Red;
+ }
+ .bg .toolbar {
+ background-color: white;
+ }
+ .lh0 {
+ line-height: 0px;
+ }
+ .lhn {
+ line-height: normal;
+ }
+ </style>
+</head>
+<body>
+ <div class="onyx">
+ <label>no content</label>
+ <div class="toolbar"></div>
+ <br />
+ <label>text only content (padding is ignored due to line height control)</label>
+ <div class="toolbar">Text</div>
+ <br />
+ <label>div content</label>
+ <div class="toolbar">
+ <div>Text in Div</div>
+ </div>
+ <br />
+ <label>input content</label>
+ <div class="toolbar">
+ <input class="" />
+ </div>
+ <br />
+ <label>input content</label>
+ <div class="toolbar">
+ <div class="icon"></div>
+ </div>
+ <br />
+ <label>input content</label>
+ <div class="toolbar">
+ <img src="menu-icon-bookmark.png" height="32"/>
+ </div>
+ <br />
+ <label>div content with min-height on toolbar (centering improper on tested user agents)</label>
+ <div class="toolbar" style="min-height: 50px;">
+ <div>Text in Div</div>
+ </div>
+ <br />
+ <label>div content with stent</label>
+ <div class="toolbar">
+ <div class="stent"></div>
+ <div>Text in Div</div>
+ </div>
+ <br />
+ <label>stented toolbars abutting in inline context, as long as the stent is the largest item the bars align. There should be no red color visible above or below each toolbar.</label>
+ <div class="inline" style="background-color: Red;">
+ <div class="toolbar">
+ <div class="stent"></div>
+ <div>Text in Div</div>
+ </div>
+ <div class="toolbar">
+ <div class="stent"></div>
+ <input class="" />
+ </div>
+ <div class="toolbar">
+ <div class="stent"></div>
+ <div class="icon"></div>
+ </div>
+ <div class="toolbar">
+ <div class="stent"></div>
+ <img src="menu-icon-bookmark.png" height="32"/>
+ </div>
+ </div>
+ </div>
+ <hr />
+ <div class="bord toolbar">
+ <div class="bord">div</div>
+ <input class="bord" />
+ <div class="bord icon"></div>
+ </div>
+ <br />
+ <div class="bord toolbar big">
+ <div class="bord">div</div>
+ <input class="bord" />
+ <div class="bord icon"></div>
+ </div>
+ <br />
+ <div class="bord toolbar big lh0">
+ <div class="bord lhn">div</div>
+ <input class="bord" />
+ <div class="bord icon"></div>
+ </div>
+ <br />
+ <div class="bord toolbar big lh0">
+ <div class="bord lhn">div</div>
+ <input class="bord" />
+ </div>
+ <br />
+ <br />
+ <div class="toolbar bord">
+ <div class="bord">div</div>
+ <input class="bord" />
+ <div class="bord inline">
+ <div class="bord">div</div>
+ <input class="bord" />
+ <div class="bord icon"></div>
+ </div>
+ <button>Button</button>
+ <div class="bord icon"></div>
+ <img class="bord" src="menu-icon-bookmark.png" height="32"/>
+ </div>
+ <br />
+ <div class="toolbar bord big">
+ <div class="bord">div</div>
+ <div class="bord inline">
+ <div class="bord">div</div>
+ <input class="bord" />
+ <div class="bord icon"></div>
+ </div>
+ <button>Button</button>
+ <div class="bord icon"></div>
+ <img class="bord"src="menu-icon-bookmark.png" height="32"/>
+ </div>
+ <br />
+ <div class="toolbar big bord">
+ <div class="bord">div</div>
+ </div>
+ <br />
+ <div class="inline bord big bg">
+ <div class="toolbar bord">
+ <div class="bord">div</div>
+ </div>
+ <div class="toolbar bord">
+ <div class="icon"></div>
+ </div>
+ <div class="toolbar bord">
+ <div class="inline">
+ <div class="icon"></div>
+ </div>
+ </div>
+ <div class="toolbar bord">
+ <div class="bord">div</div>
+ <input class="bord" />
+ <div class="inline">
+ <div class="bord">div</div>
+ <input class="bord" />
+ <div class="icon"></div>
+ </div>
+ <button>Button</button>
+ <div class="icon"></div>
+ <img src="menu-icon-bookmark.png" height="32"/>
+ </div>
+ </div>
+</body>
+</html>
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxdesigntoolbarhtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/design/toolbar.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/design/toolbar.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/design/toolbar.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,111 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>inline: onyx toolbar design</title>
+ <link href="../source/css/onyx.css" rel="stylesheet" type="text/css" />
+ <style>
+ /*
+ the 'inline' class sets up a left-to-right container, with vertically centered children
+ */
+ .inline {
+ white-space: nowrap;
+ }
+ .inline > * {
+ display: inline-block;
+ vertical-align: middle;
+ }
+ /**/
+ .toolbar {
+ padding: 8px;
+ border: 1px solid #3A3A3A;
+ background: #4C4C4C url(../images/gradient.png) repeat-x 0 bottom;
+ color: white;
+ }
+ /**/
+ .icon {
+ width: 32px;
+ height: 32px;
+ background-image: url(menu-icon-bookmark.png);
+ }
+ .bord {
+ border: 1px solid lightblue;
+ }
+ .big {
+ font-size: 48px;
+ }
+ .pad {
+ padding: 8px;
+ }
+ .mh {
+ min-height: 124px;
+ }
+ .lh {
+ line-height: 86px;
+ }
+ </style>
+</head>
+<body>
+ <label>"toolbar" tests</label>
+ <br /><br />
+ <div>
+ <label>no content</label>
+ <div class="inline toolbar"></div>
+ <br />
+
+ <label>text only content</label>
+ <div class="inline toolbar">Text</div>
+ <br />
+
+ <label>div content</label>
+ <div class="inline toolbar">
+ <div>Text in Div</div>
+ </div>
+ <br />
+
+ <label>input content</label>
+ <div class="inline toolbar">
+ <input class="" />
+ </div>
+ <br />
+
+ <label>icon content</label>
+ <div class="inline toolbar">
+ <div class="icon"></div>
+ </div>
+ <br />
+
+ <label>combo content</label>
+ <div class="inline toolbar">
+ <div>Text in Div</div>
+ <input class="" />
+ <div class="icon"></div>
+ </div>
+ <br />
+
+ <label>combo content: when the text is larger than non-text objects, vertical centering goes wonky</label>
+ <div class="inline toolbar big">
+ <div>Text in Div</div>
+ <input class="" />
+ <div class="icon"></div>
+ </div>
+ <br />
+
+ <label>controlling height</label>
+ <div class="inline toolbar big mh">
+ <div>Text in Div</div>
+ <input class="" />
+ <div class="icon"></div>
+ </div>
+ <br />
+
+ <label>controlling line-height</label>
+ <div class="inline toolbar big lh pad">
+ <div>Text in Div</div>
+ <input class="" />
+ <div class="icon"></div>
+ </div>
+ <br />
+ </div>
+</body>
+</html>
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyximagescheckboxpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/images/checkbox.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/images/checkbox.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/images/checkbox.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/images/checkbox.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/images/checkbox.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyximagesgrabbuttonpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/images/grabbutton.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/images/grabbutton.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/images/grabbutton.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/images/grabbutton.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/images/grabbutton.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyximagesgradientinvertpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/images/gradient-invert.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/images/gradient-invert.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/images/gradient-invert.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/images/gradient-invert.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/images/gradient-invert.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyximagesgradientpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/images/gradient.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/images/gradient.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/images/gradient.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/images/gradient.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/images/gradient.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyximagesmorepng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/images/more.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/images/more.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/images/more.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/images/more.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/images/more.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyximagesprogressbuttoncancelpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/images/progress-button-cancel.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/images/progress-button-cancel.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/images/progress-button-cancel.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/images/progress-button-cancel.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/images/progress-button-cancel.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyximagessearchinputcancelpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/images/search-input-cancel.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/images/search-input-cancel.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/images/search-input-cancel.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/images/search-input-cancel.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/images/search-input-cancel.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyximagessearchinputsearchpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/images/search-input-search.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/images/search-input-search.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/images/search-input-search.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/images/search-input-search.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/images/search-input-search.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyximagessliderhandlepng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/images/slider-handle.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/images/slider-handle.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/images/slider-handle.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/images/slider-handle.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/images/slider-handle.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyximagesspinnerdarkgif"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/images/spinner-dark.gif</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/images/spinner-dark.gif
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/images/spinner-dark.gif 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/images/spinner-dark.gif 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/images/spinner-dark.gif
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/gif
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyximagesspinnerlightgif"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/images/spinner-light.gif</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/images/spinner-light.gif
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/images/spinner-light.gif 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/images/spinner-light.gif 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/images/spinner-light.gif
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/gif
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyxpackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+enyo.depends(
+ "source",
+ "css"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesButtonGroupSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/ButtonGroupSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/ButtonGroupSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/ButtonGroupSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Button Group Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="ButtonGroupSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.ButtonGroupSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesButtonGroupSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/ButtonGroupSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/ButtonGroupSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/ButtonGroupSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.ButtonGroupSample",
+ classes: "onyx onyx-sample",
+ components: [
+ {classes: "onyx-sample-divider", content: "RadioGroup"},
+ {kind: "onyx.RadioGroup", onActivate:"radioActivated", components: [
+ {content: "Alpha", active: true},
+ {content: "Beta"},
+ {content: "Gamma"}
+ ]},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "TabGroup"},
+ {kind: "onyx.RadioGroup", onActivate:"tabActivated", controlClasses: "onyx-tabbutton", components: [
+ {content: "Alpha", active: true},
+ {content: "Beta"}
+ ]},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "Button Group"},
+ {kind: "Group", onActivate:"buttonActivated", classes: "onyx-sample-tools group", defaultKind: "onyx.Button", highlander: true, components: [
+ {content: "Button A", active: true, classes: "onyx-affirmative"},
+ {content: "Button B", classes: "onyx-negative"},
+ {content: "Button C", classes: "onyx-blue"}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", classes:"onyx-sample-result-box", components: [
+ {kind: "onyx.GroupboxHeader", content: "Result"},
+ {name:"result", classes:"onyx-sample-result", content:"No button tapped yet."}
+ ]}
+ ],
+ radioActivated: function(inSender, inEvent) {
+ if (inEvent.originator.getActive()) {
+ this.$.result.setContent("The \"" + inEvent.originator.getContent() + "\" radio button is selected.");
+ }
+ },
+ tabActivated: function(inSender, inEvent) {
+ if (inEvent.originator.getActive()) {
+ this.$.result.setContent("The \"" + inEvent.originator.getContent() + "\" tab button is selected.");
+ }
+ },
+ buttonActivated: function(inSender, inEvent) {
+ if (inEvent.originator.getActive()) {
+ this.$.result.setContent("The \"" + inEvent.originator.getContent() + "\" button is selected.");
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesButtonSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/ButtonSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/ButtonSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/ButtonSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Button Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="ButtonSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.ButtonSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesButtonSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/ButtonSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/ButtonSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/ButtonSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.ButtonSample",
+ classes: "onyx onyx-sample",
+ components: [
+ {classes: "onyx-sample-divider", content: "Buttons"},
+ {classes: "onyx-sample-tools", components: [
+ {kind:"onyx.Button", content: "Button", ontap:"buttonTapped"}
+ ]},
+ {classes: "onyx-sample-tools", components: [
+ {kind:"onyx.Button", content: "Affirmative", classes: "onyx-affirmative", ontap:"buttonTapped"},
+ {kind:"onyx.Button", content: "Negative", classes: "onyx-negative", ontap:"buttonTapped"},
+ {kind:"onyx.Button", content: "Blue", classes: "onyx-blue", ontap:"buttonTapped"},
+ {kind:"onyx.Button", content: "Dark", classes: "onyx-dark", ontap:"buttonTapped"},
+ {kind:"onyx.Button", content: "Custom", style: "background-color: purple; color: #F1F1F1;", ontap:"buttonTapped"}
+ ]},
+ {classes: "onyx-sample-tools", components: [
+ {kind:"onyx.Button", content: "Active", classes: "active", ontap:"buttonTapped"},
+ {kind:"onyx.Button", content: "Disabled", disabled: true, ontap:"buttonTapped"},
+ {kind:"onyx.Button", content: "Active Disabled", classes: "active", disabled: true, ontap:"buttonTapped"}
+ ]},
+ {classes: "onyx-sample-tools", components: [
+ {kind:"onyx.Button", content: "Tall Button", style: "height: 70px;", ontap:"buttonTapped"}
+ ]},
+ {classes: "onyx-sample-divider", content: "Buttons with images"},
+ {classes: "onyx-sample-tools", components: [
+ {kind: "onyx.Button", name:"Image Button", ontap:"buttonTapped", components: [
+ {tag: "img", attributes: {src: "assets/favicon.ico"}},
+ {content: "There is an image here"}
+ ]},
+ {kind: "onyx.Button", name:"Fishbowl Button", ontap:"buttonTapped", components: [
+ {kind: "onyx.Icon", src: "assets/fish_bowl.png"}
+ ]}
+ ]},
+ {kind: "onyx.Groupbox", classes:"onyx-sample-result-box", components: [
+ {kind: "onyx.GroupboxHeader", content: "Result"},
+ {name:"result", classes:"onyx-sample-result", content:"No button tapped yet."}
+ ]}
+ ],
+ buttonTapped: function(inSender, inEvent) {
+ if (inSender.content){
+ this.$.result.setContent("The \"" + inSender.getContent() + "\" button was tapped");
+ } else {
+ this.$.result.setContent("The \"" + inSender.getName() + "\" button was tapped");
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesCheckboxSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/CheckboxSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/CheckboxSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/CheckboxSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Checkbox Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="CheckboxSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.CheckboxSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesCheckboxSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/CheckboxSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/CheckboxSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/CheckboxSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.CheckboxSample",
+ classes: "onyx onyx-sample",
+ components: [
+ {classes: "onyx-sample-divider", content: "Checkboxes"},
+ {classes: "onyx-sample-tools", components: [
+ {kind:"onyx.Checkbox", onchange:"checkboxChanged"},
+ {kind:"onyx.Checkbox", onchange:"checkboxChanged"},
+ {kind:"onyx.Checkbox", onchange:"checkboxChanged", checked: true}
+ ]},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "Checkboxes Group"},
+ {kind: "Group", classes: "onyx-sample-tools group", onActivate:"groupActivated", highlander: true, components: [
+ {kind:"onyx.Checkbox", checked: true},
+ {kind:"onyx.Checkbox"},
+ {kind:"onyx.Checkbox"}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", classes:"onyx-sample-result-box", components: [
+ {kind: "onyx.GroupboxHeader", content: "Result"},
+ {name:"result", classes:"onyx-sample-result", content:"No button tapped yet."}
+ ]}
+ ],
+ checkboxChanged: function(inSender, inEvent) {
+ this.$.result.setContent(inSender.name + " was " + (inSender.getValue() ? " selected." : "deselected."));
+ },
+ ordinals: ["1st", "2nd", "3rd"],
+ groupActivated: function(inSender, inEvent) {
+ if (inEvent.originator.getActive()) {
+ var selected = inEvent.originator.indexInContainer();
+ this.$.result.setContent("The " + this.ordinals[selected] + " checkbox in the group is selected.");
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesContextualPopupSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/ContextualPopupSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/ContextualPopupSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/ContextualPopupSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <title>Contextual Popup Sample</title>
+ <!-- -->
+ <meta name="apple-mobile-web-app-capable" content="yes"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <script src="../package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="ContextualPopupSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.ContextualPopupSample({fit: true, classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesContextualPopupSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/ContextualPopupSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/ContextualPopupSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/ContextualPopupSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,240 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.ContextualPopupSample",
+ kind: "FittableRows",
+ classes: "onyx enyo-fit",
+ handlers: {
+ ontap: "tapHandler"
+ },
+ components: [
+ {kind: "onyx.Toolbar", name:"topToolbar", classes: "onyx-menu-toolbar", style:"background-color:lightgray", components: [
+ {kind:"FittableColumns", style:"width:100%;", components:[
+ {kind: "onyx.MenuDecorator", components: [
+ {kind:onyx.IconButton, src: "assets/menu-icon-bookmark.png"},
+ {kind: "onyx.ContextualPopup",
+ title:"Toolbar Button",
+ floating:true,
+ actionButtons:[
+ {content:"test1", classes: "onyx-button-warning"},
+ {content:"test2"}
+ ],
+ components: [
+ {content:"testing 1"},
+ {content:"testing 2"}
+ ]
+ }
+ ]},
+ {kind: "onyx.MenuDecorator", fit:true, style:"position:absolute;right:0;", components: [
+ {kind:onyx.IconButton, src: "assets/menu-icon-bookmark.png"},
+ {kind: "onyx.ContextualPopup",
+ title:"Toolbar Button",
+ floating:true,
+ actionButtons:[
+ {content:"test1", classes: "onyx-button-warning"},
+ {content:"test2"}
+ ],
+ components: [
+ {content:"testing 1"},
+ {content:"testing 2"},
+ {content:"testing 3"},
+ {content:"testing 4"},
+ {content:"testing 5"},
+ {content:"testing 6"}
+ ]
+ }
+ ]}
+ ]}
+ ]},
+ {kind: "Scroller", fit: true, thumb:false, components:[
+ {name:"buttonContainer", kind:"FittableRows", classes:"onyx-contextualpopup-button-container enyo-fit", components:[
+ //Top row of buttons
+ {components:[
+ {kind: "onyx.MenuDecorator", style:"display:inline-block", components: [
+ {content: "Average"},
+ {kind: "onyx.ContextualPopup",
+ title:"Average",
+ floating:true,
+ actionButtons:[
+ {content:"Press Me"}
+ ],
+ components: [
+ {content:"Item 1"},
+ {content:"Item 2"},
+ {content:"Item 3"},
+ {content:"Item 4"},
+ {content:"Item 5"}
+ ]
+ }
+ ]},
+
+ {kind: "onyx.MenuDecorator", style:"display:inline-block;float:right", components: [
+ {content:"Small"},
+ {kind: "onyx.ContextualPopup",
+ title:"Small",
+ floating:true
+ }
+ ]}
+ ]},
+ //Center row of buttons
+ {fit:true, style:"padding-top:15%;padding-bottom:15%;", components:[
+ {kind: "onyx.MenuDecorator", style:"display:inline-block;", components: [
+ {content: "Wide"},
+ {kind: "onyx.ContextualPopup",
+ style:"width:300px",
+ floating:true,
+ actionButtons:[
+ {content:"test1", classes: "onyx-button-warning"},
+ {content:"test2"}
+ ],
+ components: [
+ {kind: "Scroller", style:"min-width:150px;", horizontal:"auto", touch:true, thumb:false, components:[
+ {content:"testing 1"},
+ {content:"testing 2"}
+ ]}
+ ]
+ }
+ ]},
+ {kind: "onyx.MenuDecorator", style:"display:inline-block;float:right", components: [
+ {content:"Long"},
+ {kind: "onyx.ContextualPopup",
+ maxHeight: "200",
+ title:"Long",
+ floating:true,
+ actionButtons:[
+ {content:"Press Me"}
+ ],
+ components: [
+ {content:"testing 1"},
+ {content:"testing 2"},
+ {content:"testing 3"},
+ {content:"testing 4"},
+ {content:"testing 5"},
+ {content:"testing 6"},
+ {content:"testing 7"},
+ {content:"testing 9"},
+ {content:"testing 10"},
+ {content:"testing 11"},
+ {content:"testing 12"},
+ {content:"testing 13"},
+ {content:"testing 14"},
+ {content:"testing 15"},
+ {content:"testing 16"},
+ {content:"testing 17"},
+ {content:"testing 18"},
+ {content:"testing 19"},
+ {content:"testing 20"},
+ {content:"testing 21"},
+ {content:"testing 22"},
+ {content:"testing 23"},
+ {content:"testing 24"},
+ {content:"testing 25"},
+ {content:"testing 26"},
+ {content:"testing 27"},
+ {content:"testing 28"},
+ {content:"testing 29"},
+ {content:"testing 30"}
+ ]
+ }
+ ]}
+ ]},
+ //Bottom row of buttons
+ {components:[
+ {kind: "onyx.MenuDecorator", style:"display:inline-block;", components: [
+ {content: "Press Me"},
+ {kind: "onyx.ContextualPopup",
+ title:"Press Me",
+ floating:true,
+ style:"width:200px",
+ actionButtons:[
+ {content:"test1", classes: "onyx-button-warning"},
+ {content:"test2"}
+ ],
+ components: [
+ {content:"testing 1"},
+ {content:"testing 2"},
+ {content:"testing 3"},
+ {content:"testing 4"},
+ {content:"testing 5"},
+ {content:"testing 6"},
+ {content:"testing 7"},
+ {content:"testing 9"},
+ {content:"testing 10"}
+ ]
+ }
+ ]},
+ {kind: "onyx.MenuDecorator", style:"display:inline-block;float:right", components: [
+ {content:"Try Me"},
+ {kind: "onyx.ContextualPopup",
+ style:"width:250px",
+ title:"Try Me",
+ floating:true,
+ actionButtons:[
+ {content:"Do Nothing", classes: "onyx-button-warning"},
+ {content:"Dismiss", name:"dismiss_button"}
+ ],
+ components: [
+ {content:"Item 1"},
+ {content:"Item 2"},
+ {content:"Item 3"},
+ {content:"Item 4"},
+ {content:"Item 5"}
+ ]
+ }
+ ]}
+ ]}
+ ]}
+ ]},
+ {kind: "onyx.Toolbar", name:"bottomToolbar", classes: "onyx-menu-toolbar", style:"background-color:lightgray", components: [
+ {kind:"FittableColumns", style:"width:100%;", components:[
+ {kind: "onyx.MenuDecorator", components: [
+ {kind:onyx.IconButton, src: "assets/menu-icon-bookmark.png"},
+ {kind: "onyx.ContextualPopup",
+ title:"Toolbar Button",
+ floating:true,
+ actionButtons:[
+ {content:"test1", classes: "onyx-button-warning"},
+ {content:"test2"}
+ ],
+ components: [
+ {content:"testing 1"},
+ {content:"testing 2"},
+ {content:"testing 3"},
+ {content:"testing 4"},
+ {content:"testing 5"},
+ {content:"testing 6"}
+ ]
+ }
+ ]},
+ {kind: "onyx.MenuDecorator", fit:true, style:"position:absolute;right:0;", components: [
+ {kind:onyx.IconButton, src: "assets/menu-icon-bookmark.png"},
+ {kind: "onyx.ContextualPopup", name:"facebook",
+ title:"Toolbar Button",
+ floating:true,
+ actionButtons:[
+ {content:"test1", classes: "onyx-button-warning"},
+ {content:"Dismiss", name:"dismiss_button"}
+ ],
+ components: [
+ {content:"testing 1"},
+ {content:"testing 2"},
+ {content:"testing 3"},
+ {content:"testing 4"},
+ {content:"testing 5"},
+ {content:"testing 6"}
+ ]
+ }
+ ]}
+ ]}
+ ]}
+ ],
+ tapHandler: function(inSender, inEvent) {
+ if (inEvent.actionButton) {
+ enyo.log(inEvent.popup); //info about popup it's coming from
+ enyo.log("action button index: " + inEvent.originator.index); //index of action button
+ enyo.log("action button name: " + inEvent.originator.name); //name of action button (you can set this - see example use below)
+
+ if (inEvent.originator.name == "dismiss_button"){
+ inEvent.popup.hide();
+ }
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesDatePickerSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/DatePickerSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/DatePickerSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/DatePickerSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>DatePicker Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <script src="../../g11n/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="DatePickerSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.DatePickerSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesDatePickerSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/DatePickerSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/DatePickerSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/DatePickerSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,108 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.DatePickerSample",
+ kind: "FittableRows",
+ classes: "onyx",
+ handlers: {
+ onSelect: "updateDateValues"
+ },
+ components: [
+ {kind: "onyx.Toolbar", content:$L("Dates")},
+ {kind: "FittableColumns", style: "padding: 10px", components:[
+ {components: [
+ {content:$L("Choose Locale:"), classes:"onyx-sample-divider"},
+ {kind: "onyx.PickerDecorator", style:"padding:10px;", onSelect: "pickerHandler", components: [
+ {content: "Pick One...", style: "width: 200px"},
+ {kind: "onyx.Picker", components: [
+ {content: 'en_us', active:true},
+ {content: 'en_ca'},
+ {content: 'en_ie'},
+ {content: 'en_gb'},
+ {content: 'en_mx'},
+ {content: 'de_de'},
+ {content: 'fr_fr'},
+ {content: 'fr_ca'},
+ {content: 'it_it'},
+ {content: 'es_es'},
+ {content: 'es_mx'},
+ {content: 'es_us'}
+ ]}
+ ]}
+ ]}
+ ]},
+ {kind:"onyx.Button",content:"Get Dates", style:"margin:10px;", ontap:"getDates"},
+ {kind:"onyx.Button",content:"Reset Dates", ontap:"resetDates"},
+ {style:"width:100%;height:5px;background-color:black;margin-bottom:5px;"},
+ {caption: "Dates", style: "padding: 10px", components: [
+ {content:"DATE",classes:"onyx-sample-divider"},
+ {classes: "onyx-toolbar-inline", components: [
+ {name:"datePicker1", kind:"onyx.DatePicker"}
+ ]},
+ {kind: "onyx.Groupbox", style:"padding:5px;", components: [
+ {kind: "onyx.GroupboxHeader", content: "Value"},
+ {name:"datePicker1Value", style:"padding:15px;"}
+ ]},
+ {content:"DATE W/MIN & MAX YEARS",classes:"onyx-sample-divider"},
+ {classes: "onyx-toolbar-inline", components: [
+ {name:"datePicker2", kind:"onyx.DatePicker", minYear:2010, maxYear:2020}
+ ]},
+ {kind: "onyx.Groupbox", style:"padding:5px;", components: [
+ {kind: "onyx.GroupboxHeader", content: "Value"},
+ {name:"datePicker2Value", style:"padding:15px;"}
+ ]},
+ {content:"DATE W/DAYS HIDDEN",classes:"onyx-sample-divider"},
+ {classes: "onyx-toolbar-inline", components: [
+ {name:"datePicker3", kind:"onyx.DatePicker", dayHidden:true}
+ ]},
+ {kind: "onyx.Groupbox", style:"padding:5px;", components: [
+ {kind: "onyx.GroupboxHeader", content: "Value"},
+ {name:"datePicker3Value", style:"padding:15px;"}
+ ]},
+ {content:"DISABLED",classes:"onyx-sample-divider"},
+ {classes: "onyx-toolbar-inline", components: [
+ {name:"datePicker4", kind:"onyx.DatePicker", disabled: true}
+ ]}
+ ]}
+ ],
+ initComponents: function() {
+ this.inherited(arguments);
+ this.locale = enyo.g11n.currentLocale().getLocale();
+ },
+ pickerHandler: function(inSender, inEvent){
+ this.locale = inEvent.selected.content;
+ this.formatDate();
+ return true;
+ },
+ formatDate: function(){
+ this.$.datePicker1.setLocale(this.locale);
+ this.$.datePicker2.setLocale(this.locale);
+ this.$.datePicker3.setLocale(this.locale);
+ this.$.datePicker4.setLocale(this.locale);
+ },
+ resetDates: function(date) {
+ var d = new Date();
+ this.$.datePicker1.setValue(d);
+ this.$.datePicker2.setValue(d);
+ this.$.datePicker3.setValue(d);
+ this.$.datePicker4.setValue(d);
+ this.getDates();
+ },
+ getDates: function(){
+ var fmt = this.format();
+ this.$.datePicker1Value.setContent(fmt.format(this.$.datePicker1.getValue()));
+ this.$.datePicker2Value.setContent(fmt.format(this.$.datePicker2.getValue()));
+ // reformat the formatter to display the Date wiht only Month and year
+ fmt = this.format('my');
+ this.$.datePicker3Value.setContent(fmt.format(this.$.datePicker3.getValue()));
+ },
+ updateDateValues: function(inSender, inEvent){
+ var fmt = inEvent.name != "datePicker3" ? this.format() : this.format('my');
+ this.$[inEvent.name + "Value"].setContent(fmt.format(inEvent.value));
+ },
+ format: function(dateComponents) {
+ return (fmt = new enyo.g11n.DateFmt({
+ dateComponents: dateComponents || undefined,
+ date: 'short',
+ locale: new enyo.g11n.Locale(this.locale)
+ }));
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesDrawerSamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/DrawerSample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/DrawerSample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/DrawerSample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+.drawer-sample {
+ padding: 10px;
+}
+.drawer-sample-divider {
+ color: #F49200;
+ text-transform: uppercase;
+ font-family: Segoe UI, Prelude Medium, Helvetica, Verdana, sans-serif;
+ font-size: 14px;
+ font-weight: bold;
+ margin-bottom: 8px;
+}
+.drawer-sample-label {
+ color: #1879CD;
+ font-size: 18px;
+ text-transform: uppercase;
+}
+.drawer-sample-box {
+ border: 2px solid lightblue;
+ padding: 4px;
+ white-space: nowrap;
+ overflow:hidden;
+}
+.drawer-sample-mtb {
+ margin-top: 3px;
+ margin-bottom: 3px;
+}
+.drawer-sample-mlr {
+ margin-left: 6px;
+ margin-right: 6px;
+}
+.drawer-sample-o {
+ border-color: orange;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesDrawerSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/DrawerSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/DrawerSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/DrawerSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Drawer Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="DrawerSample.css" rel="stylesheet">
+ <script src="DrawerSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.DrawerSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesDrawerSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/DrawerSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/DrawerSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/DrawerSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.DrawerSample",
+ classes: "onyx drawer-sample",
+ components: [
+ {content: "Drawers", classes:"drawer-sample-divider"},
+ {content: "Activate (V)", classes: "drawer-sample-box drawer-sample-mtb", ontap:"activateDrawer"},
+ {name: "drawer", kind: "onyx.Drawer", components: [
+ {content: "Vertical Drawer<br>Vertical Drawer<br>Vertical Drawer<br>Vertical Drawer", allowHtml: true, classes: "drawer-sample-box drawer-sample-mtb"},
+ {components: [
+ {kind: "onyx.Checkbox", name: "animateSetting", value: true},
+ {content:"Animated", classes:"enyo-inline onyx-sample-animate-label"}
+ ]},
+ {content: "Activate (V) (Toggled Animation)", classes: "drawer-sample-box drawer-sample-mtb", ontap:"activateDrawer2"},
+ {name: "drawer2", kind: "onyx.Drawer", animated: true, components: [
+ {content: "Vertical Drawer<br>Vertical Drawer<br>Vertical Drawer<br>Vertical Drawer", allowHtml: true, classes: "drawer-sample-box drawer-sample-mtb"}
+ ]},
+ {content: "Vertical Drawer<br>Vertical Drawer<br>Vertical Drawer<br>Vertical Drawer", allowHtml: true, classes: "drawer-sample-box drawer-sample-mtb"}
+ ]},
+ {content: "Foo<br>Foo", allowHtml: true, classes: "drawer-sample-box drawer-sample-mtb"},
+ {kind: "FittableColumns", fit: true, ontap: "activateColumnsDrawer", classes: "drawer-sample-box drawer-sample-mtb drawer-sample-o", components: [
+ {content: "Activate (H)", classes: "drawer-sample-box drawer-sample-mlr"},
+ {name: "columnsDrawer", orient: "h", kind: "onyx.Drawer", open: false, components: [
+ {content: "H-Drawer", classes: "drawer-sample-box drawer-sample-mlr"}
+ ]},
+ {content: "Foo", fit: true, classes: "drawer-sample-box drawer-sample-mlr drawer-sample-o"},
+ {content: "Foo", classes: "drawer-sample-box drawer-sample-mlr"}
+ ]},
+ {content: "Foo", classes: "drawer-sample-box drawer-sample-mtb"}
+ ],
+ activateDrawer: function() {
+ this.$.drawer.setOpen(!this.$.drawer.open);
+ },
+ activateDrawer2: function() {
+ this.$.drawer2.setAnimated(this.$.animateSetting.getValue());
+ this.$.drawer2.setOpen(!this.$.drawer2.open);
+ },
+ activateColumnsDrawer: function() {
+ this.$.columnsDrawer.setOpen(!this.$.columnsDrawer.open);
+ return true;
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesGroupboxSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/GroupboxSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/GroupboxSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/GroupboxSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Groupbox Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="GroupboxSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.GroupboxSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesGroupboxSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/GroupboxSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/GroupboxSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/GroupboxSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.GroupboxSample",
+ classes: "onyx onyx-sample",
+ components: [
+ {classes: "onyx-sample-divider", content: "Groupboxes"},
+ {kind: "onyx.Groupbox", components: [
+ {kind: "onyx.GroupboxHeader", content: "Header"},
+ {content: "I'm a group item!", style: "padding: 8px;"},
+ {content: "I'm a group item!", style: "padding: 8px;"}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", components: [
+ {content: "I'm a group item!", style: "padding: 8px;"}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", components: [
+ {kind: "onyx.GroupboxHeader", content: "Header"},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", style: "width: 100%", placeholder: "Enter text here"}
+ ]},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", style: "width: 100%", value: "Middle"}
+ ]},
+ {kind: "onyx.InputDecorator", style: "background: lightblue;", components: [
+ {kind: "onyx.Input", style: "width: 100%;", value: "Last"}
+ ]}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", components: [
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", style: "width: 100%", placeholder: "Enter text here"}
+ ]}
+ ]},
+ {kind: "onyx.Groupbox", components: [
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", type: "password", style: "width: 100%", placeholder: "Enter Password"}
+ ]}
+ ]}
+ ]
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesIconButtonSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/IconButtonSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/IconButtonSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/IconButtonSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>IconButton Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="IconButtonSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.IconButtonSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesIconButtonSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/IconButtonSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/IconButtonSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/IconButtonSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,61 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.IconButtonSample",
+ classes: "onyx onyx-sample",
+ components: [
+ {classes: "onyx-sample-divider", content: "Icon"},
+ {kind: "onyx.Icon", src: "assets/menu-icon-bookmark.png" },
+ {tag: "br"},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "Icon Button"},
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png", ontap:"iconTapped"},
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png", disabled: true, ontap:"iconTapped"},
+ {tag: "br"},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "Grouped Icon Buttons"},
+ {kind: "Group", onActivate:"iconGroupActivated", components: [
+ {kind: "onyx.IconButton", active: true, src: "assets/menu-icon-bookmark.png"},
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png"},
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png"}
+ ]},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "Toggle Icon Buttons"},
+ {kind: "onyx.ToggleIconButton", onChange: "toggleChanged", src: "assets/menu-icon-bookmark.png"},
+ {kind: "onyx.ToggleIconButton", onChange: "toggleChanged", value: true, src: "assets/menu-icon-bookmark.png"},
+ {kind: "onyx.ToggleIconButton", onChange: "toggleChanged", disabled: true, src: "assets/menu-icon-bookmark.png"},
+ {kind: "onyx.ToggleIconButton", onChange: "toggleChanged", value: true, disabled: true, src: "assets/menu-icon-bookmark.png"},
+ {tag: "br"},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "Icon Buttons in Toolbar"},
+ {kind: "onyx.Toolbar", defaultKind: "onyx.IconButton", components: [
+ {src: "assets/menu-icon-bookmark.png", ontap:"iconTapped"},
+ {src: "assets/menu-icon-bookmark.png", ontap:"iconTapped"},
+ {src: "assets/menu-icon-bookmark.png", ontap:"iconTapped"},
+ {kind: "Control"},
+ {kind: "Group", tag: null, onActivate:"iconGroupActivated", defaultKind: "onyx.IconButton", components: [
+ {src: "assets/menu-icon-bookmark.png", active: true},
+ {src: "assets/menu-icon-bookmark.png"},
+ {src: "assets/menu-icon-bookmark.png"}
+ ]}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", classes:"onyx-sample-result-box", components: [
+ {kind: "onyx.GroupboxHeader", content: "Result"},
+ {name:"result", classes:"onyx-sample-result", content:"No button tapped yet."}
+ ]}
+ ],
+ iconTappedCounts: {},
+ iconTapped: function(inSender, inEvent) {
+ this.iconTappedCounts[inSender.name] = this.iconTappedCounts[inSender.name] || 0;
+ this.$.result.setContent("The icon button was tapped: " + (++this.iconTappedCounts[inSender.name]));
+ },
+ toggleChanged: function(inSender, inEvent) {
+ this.$.result.setContent(inSender.name + " was " + (inSender.getValue() ? " selected." : "deselected."));
+ },
+ ordinals: ["1st", "2nd", "3rd"],
+ iconGroupActivated: function(inSender, inEvent) {
+ if (inEvent.originator.getActive()) {
+ var selected = inEvent.originator.indexInContainer();
+ this.$.result.setContent("The " + this.ordinals[selected] + " icon button in the group is selected.");
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesInputSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/InputSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/InputSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/InputSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Input Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="InputSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.InputSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesInputSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/InputSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/InputSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/InputSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,68 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.InputSample",
+ classes: "onyx onyx-sample",
+ components: [
+ {classes: "onyx-sample-divider", content: "Inputs"},
+ {classes: "onyx-toolbar-inline", components: [
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "Enter text here", onchange:"inputChanged"}
+ ]},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "Search term", onchange:"inputChanged"},
+ {kind: "Image", src: "assets/search-input-search.png"}
+ ]},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", type:"password", placeholder: "Enter password", onchange:"inputChanged"}
+ ]},
+ {kind: "onyx.InputDecorator", components: [
+ {content: "alwaysLookFocused:"},
+ {kind: "onyx.Checkbox", onchange: "changeFocus"}
+ ]}
+ ]},
+ {classes: "onyx-toolbar-inline", components: [
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", disabled: true, value: "Disabled input"}
+ ]},
+ {kind: "onyx.InputDecorator", components: [
+ {content: "Left:"},
+ {kind: "onyx.Input", value: "Input Area", onchange:"inputChanged"},
+ {content: " :Right"}
+ ]}
+ ]},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "RichTexts"},
+ {classes: "onyx-toolbar-inline", components: [
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.RichText", style: "width: 200px;", placeholder: "Enter text here", onchange:"inputChanged"}
+ ]},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.RichText", style: "width: 200px;", placeholder: "Search term", onchange:"inputChanged"},
+ {kind: "Image", src: "assets/search-input-search.png"}
+ ]}
+ ]},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "TextAreas"},
+ {classes: "onyx-toolbar-inline", components: [
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.TextArea", placeholder: "Enter text here", onchange:"inputChanged"}
+ ]},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.TextArea", placeholder: "Search term", onchange:"inputChanged"},
+ {kind: "Image", src: "assets/search-input-search.png"}
+ ]}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", classes:"onyx-sample-result-box", components: [
+ {kind: "onyx.GroupboxHeader", content: "Result"},
+ {name:"result", classes:"onyx-sample-result", content:"No input entered yet."}
+ ]}
+ ],
+ inputChanged: function(inSender, inEvent) {
+ this.$.result.setContent("Input: " + inSender.getValue());
+ },
+ changeFocus: function(inSender, inEvent) {
+ this.$.inputDecorator.setAlwaysLooksFocused(inSender.getValue());
+ this.$.inputDecorator2.setAlwaysLooksFocused(inSender.getValue());
+ this.$.inputDecorator3.setAlwaysLooksFocused(inSender.getValue());
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesMenuSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/MenuSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/MenuSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/MenuSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Menu Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="MenuSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.MenuSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesMenuSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/MenuSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/MenuSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/MenuSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,99 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.MenuSample",
+ classes: "onyx onyx-sample",
+ components: [
+ {classes: "onyx-sample-divider", content: "Menus in Toolbars"},
+ {kind: "onyx.Toolbar", classes: "onyx-menu-toolbar", components: [
+ {kind: "onyx.MenuDecorator", onSelect: "itemSelected", components: [
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png"},
+ {kind: "onyx.Menu", components: [
+ {components: [
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png"},
+ {content: "Bookmarks"}
+ ]},
+ {content: "Favorites"},
+ {classes: "onyx-menu-divider"},
+ {content: "Recents"}
+ ]}
+ ]},
+ {kind: "onyx.MenuDecorator", onSelect: "itemSelected", components: [
+ {content: "Bookmarks menu"},
+ {kind: "onyx.Menu", components: [
+ {components: [
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png"},
+ {content: "Bookmarks"}
+ ]},
+ {content: "Favorites"},
+ {classes: "onyx-menu-divider"},
+ {content: "Recents"}
+ ]}
+ ]}
+ ]},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "Menus from Buttons"},
+ {kind: "onyx.MenuDecorator", onSelect: "itemSelected", components: [
+ {content: "Popup menu (floating)"},
+ {kind: "onyx.Menu", floating: true, components: [
+ {content: "1"},
+ {content: "2"},
+ {classes: "onyx-menu-divider"},
+ {content: "3"}
+ ]}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.MenuDecorator", onSelect: "itemSelected", components: [
+ {content: "Scrolling Popup menu"},
+ {kind: "onyx.Menu", components: [
+ {name: "menuScroller", kind: "enyo.Scroller", defaultKind: "onyx.MenuItem", vertical: "auto", classes: "enyo-unselectable", maxHeight: "200px", strategyKind: "TouchScrollStrategy", components: [
+ {content: "1"},
+ {content: "2"},
+ {classes: "onyx-menu-divider"},
+ {content: "3"},
+ {content: "4"},
+ {content: "5"},
+ {classes: "onyx-menu-divider"},
+ {content: "6"},
+ {content: "7"}
+ ]}
+ ]}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.MenuDecorator", onSelect: "itemSelected", components: [
+ {content: "Split Popup menu", kind: "onyx.Button", onActivate: "preventMenuActivate", style: "border-radius: 3px 0 0 3px;"},
+ {content: "v", allowHtml:true, style: "border-radius: 0 3px 3px 0;"},
+ {kind: "onyx.Menu", components: [
+ {content: "1"},
+ {content: "2"},
+ {classes: "onyx-menu-divider"},
+ {content: "3"}
+ ]}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", classes:"onyx-sample-result-box", components: [
+ {kind: "onyx.GroupboxHeader", content: "Result"},
+ {name:"menuSelection", classes:"onyx-sample-result", content:"No menu selection yet."}
+ ]}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ },
+ showPopup: function(inSender) {
+ var p = this.$[inSender.popup];
+ if (p) {
+ p.show();
+ }
+ },
+ preventMenuActivate: function() {
+ return true;
+ },
+ itemSelected: function(inSender, inEvent) {
+ //Menu items send an onSelect event with a reference to themselves & any directly displayed content
+ if (inEvent.originator.content){
+ this.$.menuSelection.setContent(inEvent.originator.content + " Selected");
+ } else if (inEvent.selected){
+ // Since some of the menu items do not have directly displayed content (they are kinds with subcomponents),
+ // we have to handle those items differently here.
+ this.$.menuSelection.setContent(inEvent.selected.controlAtIndex(1).content + " Selected");
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesMoreToolbarSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/MoreToolbarSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/MoreToolbarSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/MoreToolbarSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>MoreToolbar Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="MoreToolbarSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.MoreToolbarSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesMoreToolbarSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/MoreToolbarSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/MoreToolbarSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/MoreToolbarSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.MoreToolbarSample",
+ classes: "onyx onyx-sample",
+ kind: "FittableRows",
+ fit: true,
+ components: [
+ {kind: "onyx.MoreToolbar", components: [
+ {content: "More Toolbar", unmoveable: true},
+ {kind: "onyx.Button", content: "Alpha"},
+ {kind: "onyx.Button", content: "Beta"},
+ {kind: "onyx.Button", content: "Gamma", unmoveable: true},
+ {kind: "onyx.Button", content: "Epsilon"},
+ {kind: "onyx.Button", content: "Othercon"},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "pulez"}
+ ]},
+ {kind: "onyx.Button", content: "Maxizon"}
+ ]},
+ {fit: true, style: "background: lightpurple;padding:25px;", components: [
+ {content: "The \"More Toolbar\" label and the Gamma button have the unmoveable property set to true."}
+ ]},
+ {kind: "onyx.MoreToolbar", components: [
+ {content: "More Toolbar", unmoveable: true},
+ {kind: "onyx.Button", content: "Alpha"},
+ {kind: "onyx.Button", content: "Beta"},
+ {kind: "onyx.Button", content: "Gamma", unmoveable: true},
+ {kind: "onyx.Button", content: "Epsilon"},
+ {kind: "onyx.Button", content: "Othercon"},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "pulez"}
+ ]},
+ {kind: "onyx.Button", content: "Maxizon"}
+ ]}
+ ]
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesPickerSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/PickerSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/PickerSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/PickerSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Picker Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="PickerSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.PickerSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesPickerSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/PickerSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/PickerSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/PickerSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,101 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.PickerSample",
+ kind: "FittableRows",
+ classes: "onyx onyx-sample",
+ handlers: {
+ onSelect: "itemSelected"
+ },
+ components: [
+ {content: "Default Picker", classes:"onyx-sample-divider"},
+ {kind: "onyx.PickerDecorator", components: [
+ {},
+ {kind: "onyx.Picker", components: [
+ {content: "Gmail", active: true},
+ {content: "Yahoo"},
+ {content: "Outlook"},
+ {content: "Hotmail"}
+ ]}
+ ]},
+ {tag: "br"},
+ {content: "Picker with Static Button", classes:"onyx-sample-divider"},
+ {kind: "onyx.PickerDecorator", components: [
+ {kind: "onyx.PickerButton", content: "Pick One...", style: "width: 200px"},
+ {kind: "onyx.Picker", components: [
+ {content: "Hello!"},
+ {content: "I am busy."},
+ {content: "Good Bye."}
+ ]}
+ ]},
+ {tag: "br"},
+ {content: "Integer Picker", classes:"onyx-sample-divider"},
+ {classes: "onyx-toolbar-inline", components: [
+ {kind: "onyx.PickerDecorator", components: [
+ {style: "min-width: 60px;"},
+ {kind: "onyx.IntegerPicker", min: 0, max: 25, value: 5}
+ ]}
+ ]},
+ {tag: "br"},
+ {content: "Other Pickers", classes:"onyx-sample-divider"},
+ {classes: "onyx-toolbar-inline", components: [
+ {content: "Date", classes: "onyx-sample-label"},
+ {kind: "onyx.PickerDecorator", components: [
+ {},
+ {name: "monthPicker", kind: "onyx.Picker"}
+ ]},
+ {kind: "onyx.PickerDecorator", components: [
+ {style: "min-width: 60px;"},
+ {name: "dayPicker", kind: "onyx.Picker"}
+ ]},
+ {classes: "onyx-toolbar-inline", style:"margin: 0px;", components: [
+ {content: "Year", classes: "onyx-sample-label"},
+ {kind: "onyx.PickerDecorator", components: [
+ {name:"yearPickerButton", style: "min-width: 80px;"},
+ {name: "yearPicker", kind: "onyx.FlyweightPicker", count: 200, onSetupItem: "setupYear", components: [
+ {name: "year"}
+ ]}
+ ]}
+ ]}
+ ]},
+ {tag: "br"},
+ {classes: "onyx-toolbar-inline", components: [
+ {kind: "onyx.PickerDecorator", components: [
+ {},
+ {kind: "onyx.Picker", components: [
+ {content: "Gmail"},
+ {content: "Yahoo"},
+ {content: "Outlook"},
+ {content: "Hotmail", active: true}
+ ]}
+ ]}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", classes:"onyx-sample-result-box", components: [
+ {kind: "onyx.GroupboxHeader", content: "Selection"},
+ {name:"pickerSelection", classes:"onyx-sample-result", content: "Nothing picked yet."}
+ ]}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ // month
+ var months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
+ var d = new Date();
+ var i, m;
+ for (i=0; (m=months[i]); i++) {
+ this.$.monthPicker.createComponent({content: m, active: i==d.getMonth()});
+ }
+ // day
+ for (i=0; i<30; i++) {
+ this.$.dayPicker.createComponent({content: i+1, active: i==d.getDate()-1});
+ }
+ // year
+ var y = d.getYear();
+ this.$.yearPicker.setSelected(y);
+ this.$.yearPickerButton.setContent(1900+y);
+ },
+ setupYear: function(inSender, inEvent) {
+ this.$.year.setContent(1900+inEvent.index);
+ },
+ itemSelected: function(inSender, inEvent) {
+ this.$.pickerSelection.setContent(inEvent.selected.content);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesPopupSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/PopupSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/PopupSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/PopupSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Popup Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="PopupSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.PopupSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesPopupSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/PopupSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/PopupSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/PopupSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.PopupSample",
+ classes: "onyx onyx-sample",
+ components: [
+ {classes: "onyx-sample-divider", content: "Popups"},
+ {classes: "onyx-sample-tools", components: [
+ {kind: "onyx.Button", content: "Basic Popup", ontap: "showPopup", popup: "basicPopup"},
+ {name: "basicPopup", kind: "onyx.Popup", centered: true, floating: true, classes:"onyx-sample-popup", style: "padding: 10px;", content: "Popup..."},
+ {tag: "br"},
+ {kind: "onyx.Button", content: "Popup w/Spinner (Dark)", ontap: "showPopup", popup: "spinnerPopup"},
+ {name: "spinnerPopup", classes: "onyx-sample-popup", kind: "onyx.Popup", centered: true, floating: true, onHide: "popupHidden", scrim: true, components: [
+ {kind: "onyx.Spinner"},
+ {content: "Popup"}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Button", content: "Popup w/Spinner (Light)", ontap: "showPopup", popup: "lightPopup"},
+ {name: "lightPopup", classes: "onyx-sample-popup", style: "background: #eee;color: black;", kind: "onyx.Popup", centered: true, floating: true, onHide: "popupHidden", scrim: true, components: [
+ {kind: "onyx.Spinner", classes: "onyx-light"},
+ {content: "Popup"}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Button", content: "Modal Popup with Input", ontap: "showPopup", popup: "modalPopup"},
+ {name: "modalPopup", classes: "onyx-sample-popup", kind: "onyx.Popup", centered: true, modal: true, floating: true, onShow: "popupShown", onHide: "popupHidden", components: [
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input"}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Button", content: "Close", ontap: "closeModalPopup"},
+ {kind: "onyx.Button", content: "Another!", ontap: "showPopup", popup: "lightPopup"}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Button", content: "Popup at Event (right)", ontap: "showPopupAtEvent", popup: "rightEventPopup", style: "float: right;"},
+ {kind: "onyx.Button", content: "Popup at Event", ontap: "showPopupAtEvent", popup: "leftEventPopup"},
+ {name: "leftEventPopup", classes: "onyx-sample-popup", kind: "onyx.Popup", modal: true, floating: true, content: "Anchor defaults<br/>to top left corner", allowHtml: true},
+ {name: "rightEventPopup", classes: "onyx-sample-popup", kind: "onyx.Popup", modal: true, floating: true, content: "Adjusts anchor to<br/>stay in viewport", allowHtml: true}
+ ]}
+ ],
+ showPopup: function(inSender) {
+ var p = this.$[inSender.popup];
+ if (p) {
+ p.show();
+ }
+ },
+ showPopupAtEvent: function(inSender, inEvent) {
+ var p = this.$[inSender.popup];
+ if (p) {
+ p.showAtEvent(inEvent);
+ }
+ },
+ popupHidden: function() {
+ // FIXME: needed to hide ios keyboard
+ document.activeElement.blur();
+ if(this.$.modalPopup.showing) { // Refocus input on modal
+ enyo.job("focus", enyo.bind(this.$.input, "focus"), 500);
+ }
+ },
+ popupShown: function() {
+ // FIXME: does not focus input on android.
+ this.$.input.focus();
+ enyo.job("focus", enyo.bind(this.$.input, "focus"), 500);
+ },
+ closeModalPopup: function() {
+ this.$.modalPopup.hide();
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesProgressSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/ProgressSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/ProgressSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/ProgressSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Progress Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="ProgressSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.ProgressSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesProgressSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/ProgressSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/ProgressSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/ProgressSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,81 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.ProgressSample",
+ classes: "onyx onyx-sample",
+ components: [
+ {classes: "onyx-sample-divider", content: "Progress Bars"},
+ {kind: "onyx.ProgressBar", progress: 25},
+ {kind: "onyx.ProgressBar", animateStripes: false, progress: 25},
+ {kind: "onyx.ProgressBar", progress: 25, barClasses: "onyx-green"},
+ {kind: "onyx.ProgressBar", progress: 25, barClasses: "onyx-red"},
+ {kind: "onyx.ProgressBar", progress: 25, barClasses: "onyx-dark"},
+ {kind: "onyx.ProgressBar", animateStripes: false, barClasses: "onyx-light", progress: 50},
+ {kind: "onyx.ProgressBar", showStripes: false, progress: 75},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "Progress Buttons"},
+ {kind: "onyx.ProgressButton", progress: 25, onCancel:"clearValue", components: [
+ {content: "0"},
+ {content: "100", style: "float: right;"}
+ ]},
+ {kind: "onyx.ProgressButton", animateStripes: false, barClasses: "onyx-dark", progress: 50, onCancel:"clearValue"},
+ {kind: "onyx.ProgressButton", showStripes: false, progress: 75, onCancel:"clearValue"},
+ {tag: "br"},
+ {kind: "onyx.InputDecorator", style:"margin-right:10px;", components: [
+ {kind: "onyx.Input", placeholder: "Value", style:"width:50px;"}
+ ]},
+ {kind: "onyx.Button", content:"Set", classes:"onyx-sample-spaced-button", ontap:"changeValue"},
+ {kind: "onyx.Button", content:"-", classes:"onyx-sample-spaced-button", ontap:"decValue"},
+ {kind: "onyx.Button", content:"+", classes:"onyx-sample-spaced-button", ontap:"incValue"},
+ {tag: "br"},
+ {tag: "br"},
+ {kind: "onyx.Checkbox", name:"animateSetting", checked:true},
+ {content:"Animated", classes:"enyo-inline onyx-sample-animate-label"},
+ {tag: "br"},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "Sliders"},
+ {kind: "onyx.Slider", min: 10, max: 50, value: 30},
+ {tag: "br"},
+ {kind: "onyx.Slider", lockBar: false, progress: 20, value: 75},
+ {tag: "br"},
+ {name: "progressSlider", kind: "onyx.Slider", lockBar: false, value: 75},
+ {kind: "onyx.Button", content: "Toggle Progress", ontap: "toggleProgress"}
+ ],
+ changeValue: function(inSender, inEvent) {
+ for (var i in this.$) {
+ if (this.$[i].kind == "onyx.ProgressBar" || this.$[i].kind == "onyx.ProgressButton") {
+ if (this.$.animateSetting.getValue()) {
+ this.$[i].animateProgressTo(this.$.input.getValue());
+ } else {
+ this.$[i].setProgress(this.$.input.getValue());
+ }
+ }
+ }
+ },
+ incValue: function() {
+ this.$.input.setValue(Math.min(parseInt(this.$.input.getValue() || 0, 10) + 10, 100));
+ this.changeValue();
+ },
+ decValue: function() {
+ this.$.input.setValue(Math.max(parseInt(this.$.input.getValue() || 0, 10) - 10, 0));
+ this.changeValue();
+ },
+ clearValue: function(inSender, inEvent) {
+ inSender.setProgress(0);
+ },
+ toggleProgress: function() {
+ this._progressing = !this._progressing;
+ this.nextProgress();
+ },
+ nextProgress: function() {
+ if (this._progressing) {
+ enyo.requestAnimationFrame(enyo.bind(this, function() {
+ this.incrementProgress();
+ setTimeout(enyo.bind(this, "nextProgress"), 500);
+ }), this.hasNode());
+ }
+ },
+ incrementProgress: function() {
+ var p = this.$.progressSlider;
+ var i = p.min + ((p.progress - p.min + 5) % (p.max - p.min + 1));
+ p.animateProgressTo(i);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesSliderSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/SliderSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/SliderSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/SliderSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Slider Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="SliderSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.SliderSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesSliderSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/SliderSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/SliderSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/SliderSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.SliderSample",
+ classes: "onyx onyx-sample",
+ components: [
+ {classes: "onyx-sample-divider", content: "Sliders"},
+ {kind: "onyx.Slider", value: 50, onChanging:"sliderChanging", onChange:"sliderChanged"},
+ {tag: "br"},
+ {kind: "onyx.Slider", lockBar: false, value: 50, onChanging:"sliderChanging", onChange:"sliderChanged"},
+
+ {tag: "br"},
+ {kind: "onyx.InputDecorator", style:"margin-right:10px;", components: [
+ {kind: "onyx.Input", placeholder: "Value", style:"width:50px;"}
+ ]},
+ {kind: "onyx.Button", content:"Set", classes:"onyx-sample-spaced-button", ontap:"changeValue"},
+ {kind: "onyx.Button", content:"-", classes:"onyx-sample-spaced-button", ontap:"decValue"},
+ {kind: "onyx.Button", content:"+", classes:"onyx-sample-spaced-button", ontap:"incValue"},
+ {tag: "br"},
+ {tag: "br"},
+ {kind: "onyx.Checkbox", name:"animateSetting", value:true},
+ {content:"Animated", classes:"enyo-inline onyx-sample-animate-label"},
+ {kind: "onyx.Checkbox", onchange: "sliderIncrementChanged", checked: false},
+ {content: "increment by 7", classes:"enyo-inline"},
+ {tag: "br"},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", classes:"onyx-sample-result-box", components: [
+ {kind: "onyx.GroupboxHeader", content: "Result"},
+ {name:"result", classes:"onyx-sample-result", content:"No slider moved yet."}
+ ]},
+ {tag: "br"},
+ {tag: "br"},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "RangeSlider"},
+ {tag: "br"},
+ {kind: "onyx.RangeSlider", rangeMin: 100, rangeMax: 500, rangeStart: 200, rangeEnd: 400, increment: 20, showLabels: true, onChanging: "rangeSliderChanging", onChange: "rangeSliderChanged"},
+ {components: [
+ {style: "width:20%; display:inline-block; text-align:left;", content: "$100"},
+ {style: "width:60%; display:inline-block; text-align:center;", content: "$300"},
+ {style: "width:20%; display:inline-block; text-align:right;", content: "$500"}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Checkbox", onchange: "rangeSliderIncrementChanged", checked: true},
+ {content: "increment by 20", classes:"enyo-inline"},
+ {tag: "br"},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", classes:"onyx-sample-result-box", components: [
+ {kind: "onyx.GroupboxHeader", content: "Result"},
+ {name:"rangeSliderResult", classes:"onyx-sample-result", content:"RangeSlider not moved yet."}
+ ]}
+ ],
+ changeValue: function(inSender, inEvent) {
+ for (var i in this.$) {
+ if (this.$[i].kind == "onyx.Slider") {
+ if (this.$.animateSetting.getValue()) {
+ this.$[i].animateTo(this.$.input.getValue());
+ } else {
+ this.$[i].setValue(this.$.input.getValue());
+ }
+ }
+ }
+ },
+ incValue: function() {
+ this.$.input.setValue(Math.min(parseInt(this.$.input.getValue() || 0, 10) + 10, 100));
+ this.changeValue();
+ },
+ decValue: function() {
+ this.$.input.setValue(Math.max(parseInt(this.$.input.getValue() || 0, 10) - 10, 0));
+ this.changeValue();
+ },
+ sliderChanging: function(inSender, inEvent) {
+ this.$.result.setContent(inSender.name + " changing: " + Math.round(inSender.getValue()));
+ },
+ sliderChanged: function(inSender, inEvent) {
+ this.$.result.setContent(inSender.name + " changed to " + Math.round(inSender.getValue()) + ".");
+ },
+ rangeSliderIncrementChanged: function(inSender, inEvent) {
+ this.$.rangeSlider.setIncrement(inSender.getValue() ? 20 : 0);
+ },
+ sliderIncrementChanged: function(inSender, inEvent) {
+ this.$.slider2.setIncrement(inSender.getValue() ? 7 : 0);
+ this.$.slider.setIncrement(inSender.getValue() ? 7 : 0);
+ },
+ updateRangeLabels: function(slider) {
+ slider.setStartLabel("--> " + Math.floor(slider.getRangeStart()));
+ slider.setEndLabel(Math.floor(slider.getRangeEnd()) + "<--");
+ },
+ rangeSliderChanging: function(inSender, inEvent) {
+ this.updateRangeLabels(inSender);
+ this.$.rangeSliderResult.setContent("Range changing: $" + Math.round(inSender.getRangeStart()) + " - $" + Math.round(inSender.getRangeEnd()));
+ },
+ rangeSliderChanged: function(inSender, inEvent) {
+ this.updateRangeLabels(inSender);
+ this.$.rangeSliderResult.setContent("Range changed to $" + Math.round(inSender.getRangeStart()) + " - $" + Math.round(inSender.getRangeEnd()) + ".");
+ },
+ create: function() {
+ this.inherited(arguments);
+ this.updateRangeLabels(this.$.rangeSlider);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesSpinnerSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/SpinnerSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/SpinnerSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/SpinnerSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Spinner Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="SpinnerSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.SpinnerSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesSpinnerSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/SpinnerSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/SpinnerSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/SpinnerSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.SpinnerSample",
+ classes: "onyx onyx-sample",
+ handlers: {
+ onSelect: "itemSelected"
+ },
+ components: [
+ {classes: "onyx-sample-divider", content: "Light Spinner"},
+ {style:"background:black; border-radius:5px; padding:15px", components: [
+ {kind: "onyx.Spinner"}
+ ]},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "Dark Spinner"},
+ {style:"background:white; border-radius:5px; padding:15px", components: [
+ {kind: "onyx.Spinner", classes: "onyx-light"}
+ ]}
+ ]
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesTimePickerSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/TimePickerSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/TimePickerSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/TimePickerSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>TimePicker Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <script src="../../g11n/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="TimePickerSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.TimePickerSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesTimePickerSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/TimePickerSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/TimePickerSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/TimePickerSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,100 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.TimePickerSample",
+ kind: "FittableRows",
+ classes: "onyx enyo-fit",
+ handlers: {
+ onSelect: "updateTimeValues"
+ },
+ components: [
+ {kind: "onyx.Toolbar", content:$L("Times")},
+ {kind: "FittableColumns", style: "padding: 10px", components:[
+ {components: [
+ {content:$L("Choose Locale:"), classes:"onyx-sample-divider"},
+ {kind: "onyx.PickerDecorator", style:"padding:10px;", onSelect: "pickerHandler", components: [
+ {content: "Pick One...", style: "width: 200px"},
+ {kind: "onyx.Picker", components: [
+ {content: 'en_us', active:true},
+ {content: 'en_ca'},
+ {content: 'en_ie'},
+ {content: 'en_gb'},
+ {content: 'en_mx'},
+ {content: 'de_de'},
+ {content: 'fr_fr'},
+ {content: 'fr_ca'},
+ {content: 'it_it'},
+ {content: 'es_es'},
+ {content: 'es_mx'},
+ {content: 'es_us'}
+ ]}
+ ]}
+ ]}
+ ]},
+
+ {kind:"onyx.Button",content:"Get Times", style:"margin:10px;", ontap:"getTimes"},
+ {kind:"onyx.Button",content:"Reset Times", ontap:"resetTimes"},
+
+ {style:"width:100%;height:5px;background-color:black;margin-bottom:5px;"},
+ {caption: "Dates", style: "padding: 10px", components: [
+ {content:"TIME",classes:"onyx-sample-divider"},
+ {classes: "onyx-toolbar-inline", components: [
+ {name:"timePicker1", kind:"onyx.TimePicker"}
+ ]},
+ {kind: "onyx.Groupbox", style:"padding:5px;", components: [
+ {kind: "onyx.GroupboxHeader", content: "Value"},
+ {name:"timePicker1Value", style:"padding:15px;"}
+ ]},
+ {content:"TIME 24 HOUR MODE",classes:"onyx-sample-divider"},
+ {classes: "onyx-toolbar-inline", components: [
+ {name:"timePicker2", kind:"onyx.TimePicker", is24HrMode:true}
+ ]},
+ {kind: "onyx.Groupbox", style:"padding:5px;", components: [
+ {kind: "onyx.GroupboxHeader", content: "Localized Value"},
+ {name:"timePicker2Value", style:"padding:15px;"}
+ ]},
+ {content:"DISABLED",classes:"onyx-sample-divider"},
+ {classes: "onyx-toolbar-inline", components: [
+ {name:"timePicker3", kind:"onyx.TimePicker", disabled: true}
+ ]}
+ ]}
+ ],
+ initComponents: function() {
+ this.inherited(arguments);
+ this.locale = enyo.g11n.currentLocale().getLocale();
+ },
+ pickerHandler: function(inSender, inEvent){
+ this.locale = inEvent.selected.content;
+ this.formatTime();
+ return true;
+ },
+ formatTime: function(){
+ this.$.timePicker1.setLocale(this.locale);
+ this.$.timePicker2.setLocale(this.locale);
+ this.$.timePicker2.setIs24HrMode(true);
+ this.$.timePicker3.setLocale(this.locale);
+ },
+ resetTimes: function(date) {
+ var d = new Date();
+ this.$.timePicker1.setValue(d);
+ this.$.timePicker2.setValue(d);
+ this.$.timePicker3.setValue(d);
+
+ this.getTimes();
+ },
+ getTimes: function(){
+ var fmt = new enyo.g11n.DateFmt({
+ time: "short",
+ locale: new enyo.g11n.Locale(this.locale)
+ });
+
+ this.$.timePicker1Value.setContent(fmt.format(this.$.timePicker1.getValue()));
+ this.$.timePicker2Value.setContent(fmt.format(this.$.timePicker2.getValue()));
+ },
+ updateTimeValues: function(inSender, inEvent){
+ var fmt = new enyo.g11n.DateFmt({
+ time: "short",
+ locale: new enyo.g11n.Locale(this.locale)
+ });
+
+ this.$[inEvent.name + "Value"].setContent(fmt.format(inEvent.value));
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesToggleButtonSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/ToggleButtonSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/ToggleButtonSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/ToggleButtonSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>ToggleButton Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="ToggleButtonSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.ToggleButtonSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesToggleButtonSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/ToggleButtonSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/ToggleButtonSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/ToggleButtonSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.ToggleButtonSample",
+ classes: "onyx onyx-sample",
+ components: [
+ {classes: "onyx-sample-divider", content: "Toggle Buttons"},
+ {classes: "onyx-sample-tools", components: [
+ {kind:"onyx.ToggleButton", onChange:"toggleChanged", value: true},
+ {kind:"onyx.ToggleButton", onChange:"toggleChanged"},
+ {kind:"onyx.ToggleButton", onChange:"toggleChanged"},
+ {kind:"onyx.ToggleButton", onChange:"toggleChanged", value: true, disabled: true}
+ ]},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "Toggle Buttons Group"},
+ {kind: "Group", classes: "onyx-sample-tools group", onActivate:"groupActivated", highlander: true, components: [
+ {kind:"onyx.ToggleButton"},
+ {kind:"onyx.ToggleButton", value: true},
+ {kind:"onyx.ToggleButton"}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Groupbox", classes:"onyx-sample-result-box", components: [
+ {kind: "onyx.GroupboxHeader", content: "Result"},
+ {name:"result", classes:"onyx-sample-result", content:"No button tapped yet."}
+ ]}
+ ],
+ toggleChanged: function(inSender, inEvent) {
+ this.$.result.setContent(inSender.name + " was " + (inSender.getValue() ? " selected." : "deselected."));
+ },
+ ordinals: ["1st", "2nd", "3rd"],
+ groupActivated: function(inSender, inEvent) {
+ if (inEvent.originator.getActive()) {
+ var selected = inEvent.originator.indexInContainer();
+ this.$.result.setContent("The " + this.ordinals[selected] + " toggle button in the group is selected.");
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesToolbarSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/ToolbarSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/ToolbarSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/ToolbarSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Toolbar Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <script src="../../onyx/source/wip-package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="ToolbarSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.ToolbarSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesToolbarSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/ToolbarSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/ToolbarSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/ToolbarSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.ToolbarSample",
+ classes: "onyx onyx-sample",
+ components: [
+ {classes: "onyx-sample-divider", content: "ToolBar"},
+ {kind: "onyx.Toolbar", components: [
+ {kind: "onyx.Grabber"},
+ {content: "Header"},
+ {kind: "onyx.Button", content: "Button"},
+ {kind: "onyx.Button", content: "Down", classes: "active"},
+ {kind: "onyx.Button", content: "Button"},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "Input"}
+ ]},
+ {kind: "onyx.Button", content: "Right"},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "Right Input"}
+ ]},
+ {kind: "onyx.Button", content: "More Right"},
+ {content: "There's more"},
+ {kind: "onyx.Button", content: "Far Right"}
+ ]},
+ {tag: "br"},
+
+ {classes: "onyx-sample-divider", content: "Scrolling ToolBar"},
+ {kind: "Scroller", classes:"onyx-toolbar", touchOverscroll:false, touch:true, vertical:"hidden", style:"margin:0px;", thumb:false, components: [
+ {classes: "onyx-toolbar-inline", style: "white-space: nowrap;", components: [
+ {kind: "onyx.Grabber"},
+ {content: "Header"},
+ {kind: "onyx.Button", content: "Button"},
+ {kind: "onyx.Button", content: "Down", classes: "active"},
+ {kind: "onyx.Button", content: "Button"},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "Input"}
+ ]},
+ {kind: "onyx.Button", content: "Right"},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "Right Input"}
+ ]},
+ {kind: "onyx.Button", content: "More Right"},
+ {content: "There's more"},
+ {kind: "onyx.Button", content: "Far Right"}
+ ]}
+ ]},
+ {tag: "br"},
+
+ {classes: "onyx-sample-divider", content: "More ToolBar"},
+ {kind: "onyx.MoreToolbar", components: [
+ {kind: "onyx.Grabber"},
+ {content: "Header"},
+ {kind: "onyx.Button", content: "Button"},
+ {kind: "onyx.Button", content: "Down", classes: "active"},
+ {kind: "onyx.Button", content: "Button"},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "Input"}
+ ]},
+ {kind: "onyx.Button", content: "Right"},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "Right Input"}
+ ]},
+ {kind: "onyx.Button", content: "More Right"},
+ {content: "There's more"},
+ {kind: "onyx.Button", content: "Far Right"}
+ ]}
+ ]
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesTooltipSamplehtml"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/TooltipSample.html (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/TooltipSample.html (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/TooltipSample.html 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Tooltip Sample</title>
+ <!-- -->
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <!-- -->
+ <script src="../../../enyo/enyo.js" type="text/javascript"></script>
+ <script src="../../layout/package.js" type="text/javascript"></script>
+ <script src="../../onyx/package.js" type="text/javascript"></script>
+ <!-- -->
+ <link href="sample.css" rel="stylesheet">
+ <script src="TooltipSample.js" type="text/javascript"></script>
+ <!-- -->
+</head>
+<body>
+<script type="text/javascript">
+ new onyx.sample.TooltipSample({classes: "enyo-unselectable"}).renderInto(document.body);
+</script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesTooltipSamplejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/TooltipSample.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/TooltipSample.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/TooltipSample.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,92 @@
</span><ins>+enyo.kind({
+ name: "onyx.sample.TooltipSample",
+ classes: "onyx onyx-sample",
+ handlers: {
+ onSelect: "itemSelected"
+ },
+ components: [
+ {classes: "onyx-sample-divider", content: "Tooltips on Toolbar"},
+ {kind: "onyx.Toolbar", classes: "onyx-menu-toolbar", components: [
+ {kind: "onyx.TooltipDecorator", components: [
+ {kind: "onyx.Button", content: "Tooltip"},
+ {kind: "onyx.Tooltip", content: "I'm a tooltip for a button."}
+ ]},
+ {kind: "onyx.TooltipDecorator", components: [
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", style:"width:130px;", placholder: "Just an input..."}
+ ]},
+ {kind: "onyx.Tooltip", content: "I'm a tooltip for an input."}
+ ]}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.Toolbar", classes: "onyx-menu-toolbar", components: [
+ {kind: "onyx.MenuDecorator", components: [
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png"},
+ {kind: "onyx.Tooltip", content: "Bookmarks menu"},
+ {kind: "onyx.Menu", components: [
+ {components: [
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png"},
+ {content: "Bookmarks"}
+ ]},
+ {content: "Favorites"},
+ {classes: "onyx-menu-divider"},
+ {content: "Recents"}
+ ]}
+ ]},
+ {kind: "onyx.MenuDecorator", components: [
+ {content: "Bookmarks menu"},
+ {kind: "onyx.Tooltip", content: "Tap to open..."},
+ {kind: "onyx.Menu", components: [
+ {components: [
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png"},
+ {content: "Bookmarks"}
+ ]},
+ {content: "Favorites"},
+ {classes: "onyx-menu-divider"},
+ {content: "Recents"}
+ ]}
+ ]}
+ ]},
+ {tag: "br"},
+ {classes: "onyx-sample-divider", content: "Tooltips on items"},
+ {kind: "onyx.TooltipDecorator", components: [
+ {kind: "onyx.Button", content: "Tooltip"},
+ {kind: "onyx.Tooltip", content: "I'm a tooltip for a button."}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.TooltipDecorator", components: [
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", style:"width:130px;", placholder: "Just an input..."}
+ ]},
+ {kind: "onyx.Tooltip", content: "I'm a tooltip for an input."}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.MenuDecorator", components: [
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png"},
+ {kind: "onyx.Tooltip", content: "Bookmarks menu"},
+ {kind: "onyx.Menu", components: [
+ {components: [
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png"},
+ {content: "Bookmarks"}
+ ]},
+ {content: "Favorites"},
+ {classes: "onyx-menu-divider"},
+ {content: "Recents"}
+ ]}
+ ]},
+ {tag: "br"},
+ {kind: "onyx.MenuDecorator", components: [
+ {content: "Bookmarks menu"},
+ {kind: "onyx.Tooltip", content: "Tap to open..."},
+ {kind: "onyx.Menu", components: [
+ {components: [
+ {kind: "onyx.IconButton", src: "assets/menu-icon-bookmark.png"},
+ {content: "Bookmarks"}
+ ]},
+ {content: "Favorites"},
+ {classes: "onyx-menu-divider"},
+ {content: "Recents"}
+ ]}
+ ]}
+ ]
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplesassetsfaviconico"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/assets/favicon.ico</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/samples/assets/favicon.ico
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/samples/assets/favicon.ico 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/samples/assets/favicon.ico 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/samples/assets/favicon.ico
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/x-icon
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyxsamplesassetsfish_bowlpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/assets/fish_bowl.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/samples/assets/fish_bowl.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/samples/assets/fish_bowl.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/samples/assets/fish_bowl.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/samples/assets/fish_bowl.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyxsamplesassetsmenuiconbookmarkpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/assets/menu-icon-bookmark.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/samples/assets/menu-icon-bookmark.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/samples/assets/menu-icon-bookmark.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/samples/assets/menu-icon-bookmark.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/samples/assets/menu-icon-bookmark.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyxsamplesassetssearchinputsearchpng"></a>
<div class="binary"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/assets/search-input-search.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: 2013/sayaksarkar/trunk/lib/onyx/samples/assets/search-input-search.png
</span><span class="cx">===================================================================
</span><del>--- 2013/sayaksarkar/trunk/lib/onyx/samples/assets/search-input-search.png 2013-07-23 12:44:16 UTC (rev 2145)
</del><ins>+++ 2013/sayaksarkar/trunk/lib/onyx/samples/assets/search-input-search.png 2013-07-23 16:49:28 UTC (rev 2146)
</ins><span class="cx">Property changes on: 2013/sayaksarkar/trunk/lib/onyx/samples/assets/search-input-search.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="2013sayaksarkartrunklibonyxsamplespackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+enyo.depends(
+ "sample.css",
+ "DrawerSample.css",
+ "ButtonGroupSample.js",
+ "ButtonSample.js",
+ "CheckboxSample.js",
+ "GroupboxSample.js",
+ "IconButtonSample.js",
+ "InputSample.js",
+ "PopupSample.js",
+ "ProgressSample.js",
+ "SliderSample.js",
+ "ToggleButtonSample.js",
+ "ToolbarSample.js",
+ "DrawerSample.js",
+ "MenuSample.js",
+ "TooltipSample.js",
+ "SpinnerSample.js",
+ "PickerSample.js",
+ "DatePickerSample.js",
+ "TimePickerSample.js",
+ "ContextualPopupSample.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsamplessamplecss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/samples/sample.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/samples/sample.css (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/samples/sample.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+.onyx-sample {
+ padding: 10px;
+}
+.onyx-sample-tools {
+ padding-bottom:10px;
+}
+.onyx-sample-tools > * {
+ margin: 3px;
+}
+.onyx-sample-divider {
+ color: #F49200;
+ text-transform: uppercase;
+ font-family: Segoe UI, Prelude Medium, Helvetica, Verdana, sans-serif;
+ font-size: 14px;
+ font-weight: bold;
+ margin-bottom: 8px;
+}
+.onyx-sample-result-box {
+ width:100%;
+}
+.onyx-sample-result {
+ padding:8px;
+}
+.onyx-sample-spaced-button {
+ margin:3px;
+}
+.onyx-sample-animate-label {
+ vertical-align:middle;
+ padding-left:5px;
+ margin-right: 15px;
+}
+.onyx-sample-label {
+ color: #1879CD;
+ font-size: 18px;
+ text-transform: uppercase;
+}
+.onyx-sample-popup {
+ font-size: 30px;
+ text-align: center;
+}
+.onyx-contextualpopup-button-container{
+ padding:10px;
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceButtonjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Button.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Button.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Button.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+/**
+ _onyx.Button_ is an <a href="#enyo.Button">enyo.Button</a> with Onyx styling
+ applied. The color of the button may be customized by specifying a
+ background color.
+
+ The *onyx-affirmative*, *onyx-negative*, and *onyx-blue* classes provide
+ some built-in presets.
+
+ {kind: "onyx.Button", content: "Button"},
+ {kind: "onyx.Button", content: "Affirmative", classes: "onyx-affirmative"},
+ {kind: "onyx.Button", content: "Negative", classes: "onyx-negative"},
+ {kind: "onyx.Button", content: "Blue", classes: "onyx-blue"},
+ {kind: "onyx.Button", content: "Custom", style: "background-color: purple; color: #F1F1F1;"}
+
+ For more information, see the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Buttons">Buttons</a> in the
+ Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "onyx.Button",
+ kind: "enyo.Button",
+ classes: "onyx-button enyo-unselectable",
+ //* @protected
+ create: function() {
+ //workaround for FirefoxOS which doesn't support :active:hover css selectors
+ if(enyo.platform.firefoxOS) {
+ this.handlers.ondown = "down";
+ this.handlers.onleave = "leave";
+ }
+ this.inherited(arguments);
+ },
+ down: function(inSender, inEvent) {
+ this.addClass("pressed");
+ },
+ leave: function(inSender, inEvent) {
+ this.removeClass("pressed");
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceCheckboxjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Checkbox.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Checkbox.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Checkbox.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+/**
+ A box that shows or hides a check mark when clicked.
+ The onChange event is fired when it is clicked. Use getValue() to fetch
+ the checked status.
+
+ {kind: "onyx.Checkbox", onchange: "checkboxClicked"}
+
+ checkboxClicked: function(inSender) {
+ if (inSender.getValue()) {
+ this.log("I've been checked!");
+ }
+ }
+*/
+enyo.kind({
+ name: "onyx.Checkbox",
+ classes: "onyx-checkbox",
+ //* @protected
+ kind: enyo.Checkbox,
+ tag: "div",
+ handlers: {
+ // prevent double onchange bubble in IE
+ onclick: ""
+ },
+ tap: function(inSender, e) {
+ if (!this.disabled) {
+ this.setChecked(!this.getChecked());
+ this.bubble("onchange");
+ }
+ return !this.disabled;
+ },
+ dragstart: function() {
+ // Override enyo.Input dragstart handler, to allow drags to propagate for Checkbox
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceContextualPopupjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/ContextualPopup.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/ContextualPopup.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/ContextualPopup.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,514 @@
</span><ins>+/**
+ _onyx.ContextualPopup_ is a subkind of <a href="#enyo.Popup">enyo.Popup</a>.
+ Contextual popups serve as child windows that appear near the point of
+ initiation. Use them for prompting users to select from a defined set of
+ options; for conducting other quick, single-step interactions in which
+ context should be maintained; and for presenting simple views, such as
+ previews.
+
+ A contextual popup is meant to be used in conjunction with a decorator, such
+ as an <a href="#onyx.MenuDecorator">onyx.MenuDecorator</a>. The decorator
+ couples the popup with an activating control, which may be a button or any
+ other control with an _onActivate_ event. When the control is activated, the
+ popup shows itself in the correct position relative to the activator.
+
+ Note that, by default, the popup is not floating, so toolbars and controls
+ with high z-index values may obscure it. You may set the _floating_ property
+ to true to have the popup always appear on top; however, the popup will not
+ be in the containing document's flow and so will not scroll with the
+ document.
+
+ In addition, while contextual popups have their own positioning logic, they
+ do not currently have their own sizing logic, so be sure to take this into
+ account when using them.
+
+ {kind: "onyx.MenuDecorator", components: [
+ {content: "Show Popup"},
+ {kind: "onyx.ContextualPopup",
+ title: "Sample Popup",
+ actionButtons: [
+ {content:"Button 1", classes: "onyx-button-warning"},
+ {content:"Button 2"}
+ ],
+ components: [
+ {content:"Sample component in popup"}
+ ]
+ }
+ ]}
+*/
+
+enyo.kind({
+ name: "onyx.ContextualPopup",
+ kind: "enyo.Popup",
+ modal: true,
+ autoDismiss: true,
+ floating:false,
+ classes: "onyx-contextual-popup enyo-unselectable",
+ published: {
+ //* Maximum height of the menu
+ maxHeight: 100,
+ //* Toggle scrolling
+ scrolling: true,
+ //* Popup title content
+ title: undefined,
+ //* Buttons at bottom of popup
+ actionButtons: []
+ },
+
+ //layout parameters
+ vertFlushMargin:60, //vertical flush layout margin
+ horizFlushMargin:50, //horizontal flush layout margin
+ widePopup:200, //popups wider than this value are considered wide (for layout purposes)
+ longPopup:200, //popups longer than this value are considered long (for layout purposes)
+ horizBuffer:16, //do not allow horizontal flush popups past spec'd amount of buffer space on left/right screen edge
+
+ events: {
+ onTap: ""
+ },
+ handlers: {
+ onActivate: "itemActivated",
+ onRequestShowMenu: "requestShow",
+ onRequestHideMenu: "requestHide"
+ },
+ components: [
+ {name:"title", classes:"onyx-contextual-popup-title"},
+ {classes:"onyx-contextual-popup-scroller", components:[
+ {name:"client", kind: "enyo.Scroller", vertical:"auto", classes:"enyo-unselectable", thumb:false, strategyKind: "TouchScrollStrategy"}
+ ]},
+ {name:"actionButtons", classes:"onyx-contextual-popup-action-buttons"}
+ ],
+ scrollerName: "client",
+ create: function() {
+ this.inherited(arguments);
+ this.maxHeightChanged();
+ this.titleChanged();
+ this.actionButtonsChanged();
+ },
+ getScroller: function() {
+ return this.$[this.scrollerName];
+ },
+ titleChanged: function(){
+ this.$.title.setContent(this.title);
+ },
+ actionButtonsChanged: function(){
+ for (var i=0;i<this.actionButtons.length;i++){
+ this.$.actionButtons.createComponent({
+ kind:"onyx.Button",
+ content:this.actionButtons[i].content,
+ classes: this.actionButtons[i].classes + " onyx-contextual-popup-action-button",
+ name: this.actionButtons[i].name ? this.actionButtons[i].name : "ActionButton"+i,
+ index: i,
+ tap: enyo.bind(this,this.tapHandler)
+ });
+ }
+ },
+ tapHandler: function(inSender, inEvent){
+ //Populate event fields with origination info
+ inEvent.actionButton = true;
+ inEvent.popup = this;
+ this.bubble("ontap",inEvent);
+ return true;
+ },
+ maxHeightChanged: function() {
+ if (this.scrolling) {
+ this.getScroller().setMaxHeight(this.maxHeight + "px");
+ }
+ },
+ itemActivated: function(inSender, inEvent) {
+ inEvent.originator.setActive(false);
+ return true;
+ },
+ showingChanged: function() {
+ this.inherited(arguments);
+ if (this.scrolling) {
+ this.getScroller().setShowing(this.showing);
+ }
+ this.adjustPosition();
+ },
+ requestShow: function(inSender, inEvent) {
+ var n = inEvent.activator.hasNode();
+ if (n) {
+ this.activatorOffset = this.getPageOffset(n);
+ }
+ this.show();
+ return true;
+ },
+ applyPosition: function(inRect) {
+ var s = "";
+ for (var n in inRect) {
+ s += (n + ":" + inRect[n] + (isNaN(inRect[n]) ? "; " : "px; "));
+ }
+ this.addStyles(s);
+ },
+ getPageOffset: function(inNode) {
+ var r = this.getBoundingRect(inNode);
+
+ var pageYOffset = (window.pageYOffset === undefined) ? document.documentElement.scrollTop : window.pageYOffset;
+ var pageXOffset = (window.pageXOffset === undefined) ? document.documentElement.scrollLeft : window.pageXOffset;
+ var rHeight = (r.height === undefined) ? (r.bottom - r.top) : r.height;
+ var rWidth = (r.width === undefined) ? (r.right - r.left) : r.width;
+
+ return {top: r.top + pageYOffset, left: r.left + pageXOffset, height: rHeight, width: rWidth};
+ },
+ //* @protected
+ /* Adjusts the popup position + nub location & direction
+ */
+ adjustPosition: function() {
+ if (this.showing && this.hasNode()) {
+ /****ContextualPopup positioning rules:
+ 1. Activator Location:
+ a. If activator is located in a corner then position using a flush style.
+ i. Attempt vertical first.
+ ii. Horizontal if vertical doesn't fit.
+ b. If not in a corner then check if the activator is located in one of the 4 "edges" of the view & position the
+ following way if so:
+ i. Activator is in top edge, position popup below it.
+ ii. Activator is in bottom edge, position popup above it.
+ iii. Activator is in left edge, position popup to the right of it.
+ iv. Activator is in right edge, position popup to the left of it.
+
+ 2. Screen Size - the pop-up should generally extend in the direction where there’s room for it.
+ Note: no specific logic below for this rule since it is built into the positioning functions, ie we attempt to never
+ position a popup where there isn't enough room for it.
+
+ 3. Popup Size:
+ i. If popup content is wide, use top or bottom positioning.
+ ii. If popup content is long, use horizontal positioning.
+
+ 4. Favor top or bottom:
+ If all the above rules have been followed and location can still vary then favor top or bottom positioning.
+
+ 5. If top or bottom will work, favor bottom.
+ Note: no specific logic below for this rule since it is built into the vertical position functions, ie we attempt to
+ use a bottom position for the popup as much possible. Additionally within the vetical position function we center the
+ popup if the activator is at the vertical center of the view.
+ ****/
+ this.resetPositioning();
+ var innerWidth = this.getViewWidth();
+ var innerHeight = this.getViewHeight();
+
+ //These are the view "flush boundaries"
+ var topFlushPt = this.vertFlushMargin;
+ var bottomFlushPt = innerHeight - this.vertFlushMargin;
+ var leftFlushPt = this.horizFlushMargin;
+ var rightFlushPt = innerWidth - this.horizFlushMargin;
+
+ //Rule 1 - Activator Location based positioning
+ //if the activator is in the top or bottom edges of the view, check if the popup needs flush positioning
+ if ((this.activatorOffset.top + this.activatorOffset.height) < topFlushPt || this.activatorOffset.top > bottomFlushPt) {
+ //check/try vertical flush positioning (rule 1.a.i)
+ if (this.applyVerticalFlushPositioning(leftFlushPt, rightFlushPt)) {
+ return;
+ }
+
+ //if vertical doesn't fit then check/try horizontal flush (rule 1.a.ii)
+ if (this.applyHorizontalFlushPositioning(leftFlushPt, rightFlushPt)) {
+ return;
+ }
+
+ //if flush positioning didn't work then try just positioning vertically (rule 1.b.i & rule 1.b.ii)
+ if (this.applyVerticalPositioning()){
+ return;
+ }
+ //otherwise check if the activator is in the left or right edges of the view & if so try horizontal positioning
+ } else if ((this.activatorOffset.left + this.activatorOffset.width) < leftFlushPt || this.activatorOffset.left > rightFlushPt) {
+ //if flush positioning didn't work then try just positioning horizontally (rule 1.b.iii & rule 1.b.iv)
+ if (this.applyHorizontalPositioning()){
+ return;
+ }
+ }
+
+ //Rule 2 - no specific logic below for this rule since it is inheritent to the positioning functions, ie we attempt to never
+ //position a popup where there isn't enough room for it.
+
+ //Rule 3 - Popup Size based positioning
+ var clientRect = this.getBoundingRect(this.node);
+
+ //if the popup is wide then use vertical positioning
+ if (clientRect.width > this.widePopup) {
+ if (this.applyVerticalPositioning()){
+ return;
+ }
+ }
+ //if the popup is long then use horizontal positioning
+ else if (clientRect.height > this.longPopup) {
+ if (this.applyHorizontalPositioning()){
+ return;
+ }
+ }
+
+ //Rule 4 - Favor top or bottom positioning
+ if (this.applyVerticalPositioning()) {
+ return;
+ }
+ //but if thats not possible try horizontal
+ else if (this.applyHorizontalPositioning()){
+ return;
+ }
+
+ //Rule 5 - no specific logic below for this rule since it is built into the vertical position functions, ie we attempt to
+ // use a bottom position for the popup as much possible.
+ }
+ },
+ //move the popup below or above the activator & verify that it fits on screen
+ initVerticalPositioning: function() {
+ this.resetPositioning();
+ this.addClass("vertical");
+
+ var clientRect = this.getBoundingRect(this.node);
+ var innerHeight = this.getViewHeight();
+
+ if (this.floating){
+ if (this.activatorOffset.top < (innerHeight / 2)) {
+ this.applyPosition({top: this.activatorOffset.top + this.activatorOffset.height, bottom: "auto"});
+ this.addClass("below");
+ } else {
+ this.applyPosition({top: this.activatorOffset.top - clientRect.height, bottom: "auto"});
+ this.addClass("above");
+ }
+ } else {
+ //if the popup's bottom goes off the screen then put it on the top of the invoking control
+ if ((clientRect.top + clientRect.height > innerHeight) && ((innerHeight - clientRect.bottom) < (clientRect.top - clientRect.height))){
+ this.addClass("above");
+ } else {
+ this.addClass("below");
+ }
+ }
+
+ //if moving the popup above or below the activator puts it past the edge of the screen then vertical doesn't work
+ clientRect = this.getBoundingRect(this.node);
+ if ((clientRect.top + clientRect.height) > innerHeight || clientRect.top < 0){
+ return false;
+ }
+
+ return true;
+ },
+ applyVerticalPositioning: function() {
+ //if we can't fit the popup above or below the activator then forget vertical positioning
+ if (!this.initVerticalPositioning()) {
+ return false;
+ }
+
+ var clientRect = this.getBoundingRect(this.node);
+ var innerWidth = this.getViewWidth();
+
+ if (this.floating){
+ //Get the left edge delta to horizontally center the popup
+ var centeredLeft = this.activatorOffset.left + this.activatorOffset.width/2 - clientRect.width/2;
+ if (centeredLeft + clientRect.width > innerWidth) {//popup goes off right edge of the screen if centered
+ this.applyPosition({left: this.activatorOffset.left + this.activatorOffset.width - clientRect.width});
+ this.addClass("left");
+ } else if (centeredLeft < 0) {//popup goes off left edge of the screen if centered
+ this.applyPosition({left:this.activatorOffset.left});
+ this.addClass("right");
+ } else {//center the popup
+ this.applyPosition({left: centeredLeft});
+ }
+
+ } else {
+ //Get the left edge delta to horizontally center the popup
+ var centeredLeftDelta = this.activatorOffset.left + this.activatorOffset.width/2 - clientRect.left - clientRect.width/2;
+ if (clientRect.right + centeredLeftDelta > innerWidth) {//popup goes off right edge of the screen if centered
+ this.applyPosition({left: this.activatorOffset.left + this.activatorOffset.width - clientRect.right});
+ this.addRemoveClass("left", true);
+ } else if (clientRect.left + centeredLeftDelta < 0) {//popup goes off left edge of the screen if centered
+ this.addRemoveClass("right", true);
+ } else {//center the popup
+ this.applyPosition({left: centeredLeftDelta});
+ }
+ }
+
+ return true;
+ },
+ applyVerticalFlushPositioning: function(leftFlushPt, rightFlushPt) {
+ //if we can't fit the popup above or below the activator then forget vertical positioning
+ if (!this.initVerticalPositioning()) {
+ return false;
+ }
+
+ var clientRect = this.getBoundingRect(this.node);
+ var innerWidth = this.getViewWidth();
+
+ //If the activator's right side is within our left side cut off use flush positioning
+ if ((this.activatorOffset.left + this.activatorOffset.width/2) < leftFlushPt){
+ //if the activator's left edge is too close or past the screen left edge
+ if (this.activatorOffset.left + this.activatorOffset.width/2 < this.horizBuffer){
+ this.applyPosition({left:this.horizBuffer + (this.floating ? 0 : -clientRect.left)});
+ } else {
+ this.applyPosition({left:this.activatorOffset.width/2 + (this.floating ? this.activatorOffset.left : 0)});
+ }
+
+ this.addClass("right");
+ this.addClass("corner");
+ return true;
+ }
+ //If the activator's left side is within our right side cut off use flush positioning
+ else if (this.activatorOffset.left + this.activatorOffset.width/2 > rightFlushPt) {
+ if ((this.activatorOffset.left+this.activatorOffset.width/2) > (innerWidth-this.horizBuffer)){
+ this.applyPosition({left:innerWidth - this.horizBuffer - clientRect.right});
+ } else {
+ this.applyPosition({left: (this.activatorOffset.left + this.activatorOffset.width/2) - clientRect.right});
+ }
+ this.addClass("left");
+ this.addClass("corner");
+ return true;
+ }
+
+ return false;
+ },
+ //move the popup left or right of the activator & verify that it fits on screen
+ initHorizontalPositioning: function() {
+ this.resetPositioning();
+
+ var clientRect = this.getBoundingRect(this.node);
+ var innerWidth = this.getViewWidth();
+
+ //adjust horizontal positioning of the popup & nub vertical positioning
+ if (this.floating){
+ if ((this.activatorOffset.left + this.activatorOffset.width) < innerWidth/2) {
+ this.applyPosition({left: this.activatorOffset.left + this.activatorOffset.width});
+ this.addRemoveClass("left", true);
+ } else {
+ this.applyPosition({left: this.activatorOffset.left - clientRect.width});
+ this.addRemoveClass("right", true);
+ }
+ } else {
+ if (this.activatorOffset.left - clientRect.width > 0) {
+ this.applyPosition({left: this.activatorOffset.left - clientRect.left - clientRect.width});
+ this.addRemoveClass("right", true);
+ } else {
+ this.applyPosition({left: this.activatorOffset.width});
+ this.addRemoveClass("left", true);
+ }
+ }
+ this.addRemoveClass("horizontal", true);
+
+ //if moving the popup left or right of the activator puts it past the edge of the screen then horizontal won't work
+ clientRect = this.getBoundingRect(this.node);
+ if (clientRect.left < 0 || (clientRect.left + clientRect.width) > innerWidth){
+ return false;
+ }
+ return true;
+
+ },
+ applyHorizontalPositioning: function() {
+ //if we can't fit the popup left or right of the activator then forget horizontal positioning
+ if (!this.initHorizontalPositioning()) {
+ return false;
+ }
+
+ var clientRect = this.getBoundingRect(this.node);
+ var innerHeight = this.getViewHeight();
+ var activatorCenter = this.activatorOffset.top + this.activatorOffset.height/2;
+
+ if (this.floating){
+ //if the activator's center is within 10% of the center of the view, vertically center the popup
+ if ((activatorCenter >= (innerHeight/2 - 0.05 * innerHeight)) && (activatorCenter <= (innerHeight/2 + 0.05 * innerHeight))) {
+ this.applyPosition({top: this.activatorOffset.top + this.activatorOffset.height/2 - clientRect.height/2, bottom: "auto"});
+ } else if (this.activatorOffset.top + this.activatorOffset.height < innerHeight/2) { //the activator is in the top 1/2 of the screen
+ this.applyPosition({top: this.activatorOffset.top - this.activatorOffset.height, bottom: "auto"});
+ this.addRemoveClass("high", true);
+ } else { //otherwise the popup will be positioned in the bottom 1/2 of the screen
+ this.applyPosition({top: this.activatorOffset.top - clientRect.height + this.activatorOffset.height*2, bottom: "auto"});
+ this.addRemoveClass("low", true);
+ }
+ } else {
+ //if the activator's center is within 10% of the center of the view, vertically center the popup
+ if ((activatorCenter >= (innerHeight/2 - 0.05 * innerHeight)) && (activatorCenter <= (innerHeight/2 + 0.05 * innerHeight))) {
+ this.applyPosition({top: (this.activatorOffset.height - clientRect.height)/2});
+ } else if (this.activatorOffset.top + this.activatorOffset.height < innerHeight/2) { //the activator is in the top 1/2 of the screen
+ this.applyPosition({top: -this.activatorOffset.height});
+ this.addRemoveClass("high", true);
+ } else { //otherwise the popup will be positioned in the bottom 1/2 of the screen
+ this.applyPosition({top: clientRect.top - clientRect.height - this.activatorOffset.top + this.activatorOffset.height});
+ this.addRemoveClass("low", true);
+ }
+ }
+ return true;
+ },
+ applyHorizontalFlushPositioning: function(leftFlushPt, rightFlushPt) {
+ //if we can't fit the popup left or right of the activator then forget vertical positioning
+ if (!this.initHorizontalPositioning()) {
+ return false;
+ }
+
+ var clientRect = this.getBoundingRect(this.node);
+ var innerWidth = this.getViewWidth();
+
+ //adjust vertical positioning (high or low nub & popup position)
+ if (this.floating){
+ if (this.activatorOffset.top < (innerHeight/2)){
+ this.applyPosition({top: this.activatorOffset.top + this.activatorOffset.height/2});
+ this.addRemoveClass("high", true);
+ } else {
+ this.applyPosition({top:this.activatorOffset.top + this.activatorOffset.height/2 - clientRect.height});
+ this.addRemoveClass("low", true);
+ }
+ } else {
+ if (((clientRect.top + clientRect.height) > innerHeight) && ((innerHeight - clientRect.bottom) < (clientRect.top - clientRect.height))) {
+ this.applyPosition({top: clientRect.top - clientRect.height - this.activatorOffset.top - this.activatorOffset.height/2});
+ this.addRemoveClass("low", true);
+ } else {
+ this.applyPosition({top: this.activatorOffset.height/2});
+ this.addRemoveClass("high", true);
+ }
+ }
+
+ //If the activator's right side is within our left side cut off use flush positioning
+ if ((this.activatorOffset.left + this.activatorOffset.width) < leftFlushPt){
+ this.addClass("left");
+ this.addClass("corner");
+ return true;
+ }
+ //If the activator's left side is within our right side cut off use flush positioning
+ else if (this.activatorOffset.left > rightFlushPt) {
+ this.addClass("right");
+ this.addClass("corner");
+ return true;
+ }
+
+ return false;
+ },
+ getBoundingRect: function(inNode){
+ // getBoundingClientRect returns top/left values which are relative to the viewport and not absolute
+ var o = inNode.getBoundingClientRect();
+ if (!o.width || !o.height) {
+ return {
+ left: o.left,
+ right: o.right,
+ top: o.top,
+ bottom: o.bottom,
+ width: o.right - o.left,
+ height: o.bottom - o.top
+ };
+ }
+ return o;
+ },
+ getViewHeight: function() {
+ return (window.innerHeight === undefined) ? document.documentElement.clientHeight : window.innerHeight;
+ },
+ getViewWidth: function() {
+ return (window.innerWidth === undefined) ? document.documentElement.clientWidth : window.innerWidth;
+ },
+ resetPositioning: function() {
+ this.removeClass("right");
+ this.removeClass("left");
+ this.removeClass("high");
+ this.removeClass("low");
+ this.removeClass("corner");
+ this.removeClass("below");
+ this.removeClass("above");
+ this.removeClass("vertical");
+ this.removeClass("horizontal");
+
+ this.applyPosition({left: "auto"});
+ this.applyPosition({top: "auto"});
+ },
+ resizeHandler: function() {
+ this.inherited(arguments);
+ this.adjustPosition();
+ },
+ requestHide: function(){
+ this.setShowing(false);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceDatePickerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/DatePicker.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/DatePicker.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/DatePicker.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,205 @@
</span><ins>+/**
+ _onyx.DatePicker_ is a group of <a href="#onyx.Picker">onyx.Picker</a>
+ controls displaying the current date. The user may change the _day_,
+ _month_, and _year_ values.
+
+ By default, _DatePicker_ tries to determine the current locale and use its
+ rules to format the date (including the month name). In order to do this
+ successfully, the _g11n_ library must be loaded; if it is not loaded, the
+ control defaults to using standard U.S. date format.
+
+ The _day_ field is automatically populated with the proper number of days
+ for the selected month and year.
+ */
+enyo.kind({
+ name: "onyx.DatePicker",
+ classes: "onyx-toolbar-inline",
+ published: {
+ //* If true, control is shown as disabled, and user can't select new values
+ disabled: false,
+ /**
+ Current locale used for formatting. Can be set after control
+ creation, in which case the control will be updated to reflect the
+ new value.
+ */
+ locale: "en_us",
+ //* If true, the day field is hidden
+ dayHidden: false,
+ //* If true, the month field is hidden
+ monthHidden: false,
+ //* If true, the year field is hidden
+ yearHidden: false,
+ //* Optional minimum year value
+ minYear: 1900,
+ //* Optional maximum year value
+ maxYear: 2099,
+ /**
+ The current Date object. When a Date object is passed to _setValue_,
+ the control is updated to reflect the new value. _getValue_ returns
+ a Date object.
+ */
+ value: null
+ },
+ events: {
+ /**
+ Fires when one of the DatePicker's fields is selected.
+
+ _inEvent.name_ contains the name of the DatePicker that generated
+ the event.
+
+ _inEvent.value_ contains the current Date value of the control.
+ */
+ onSelect: ""
+ },
+ create: function() {
+ this.inherited(arguments);
+ if (enyo.g11n) {
+ this.locale = enyo.g11n.currentLocale().getLocale();
+ }
+ this.initDefaults();
+ },
+ initDefaults: function() {
+ // Fall back to en_us as default
+ var months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
+
+ //Attempt to use the g11n lib (ie assume it is loaded)
+ if (enyo.g11n) {
+ this._tf = new enyo.g11n.Fmts({locale:this.locale});
+ months = this._tf.getMonthFields();
+ }
+
+ this.setupPickers(this._tf ? this._tf.getDateFieldOrder() : 'mdy');
+
+ this.dayHiddenChanged();
+ this.monthHiddenChanged();
+ this.yearHiddenChanged();
+
+ //Fill month, year & day pickers with values
+ var d = this.value = this.value || new Date();
+ for (var i=0,m; (m=months[i]); i++) {
+ this.$.monthPicker.createComponent({content: m, value:i, active: i==d.getMonth()});
+ }
+
+ var y = d.getFullYear();
+ this.$.yearPicker.setSelected(y-this.minYear);
+
+ for (i=1; i<=this.monthLength(d.getYear(), d.getMonth()); i++) {
+ this.$.dayPicker.createComponent({content:i, value:i, active: i==d.getDate()});
+ }
+ },
+ monthLength: function(inYear, inMonth) {
+ // determine number of days in a particular month/year
+ return 32 - new Date(inYear, inMonth, 32).getDate();
+ },
+ setupYear: function(inSender, inEvent) {
+ this.$.year.setContent(this.minYear+inEvent.index);
+ },
+ setupPickers: function(ordering) {
+ var orderingArr = ordering.split("");
+ var o,f,l;
+ for(f = 0, l = orderingArr.length; f < l; f++) {
+ o = orderingArr[f];
+ switch (o){
+ case 'd': this.createDay();
+ break;
+ case 'm': this.createMonth();
+ break;
+ case 'y': this.createYear();
+ break;
+ default: break;
+ }
+ }
+ },
+ createYear: function() {
+ var yearCount = this.maxYear - this.minYear;
+ this.createComponent(
+ {kind: "onyx.PickerDecorator", onSelect: "updateYear", components: [
+ {classes:"onyx-datepicker-year", name: "yearPickerButton", disabled: this.disabled},
+ {name: "yearPicker", kind: "onyx.FlyweightPicker", count: ++yearCount, onSetupItem: "setupYear", components: [
+ {name: "year"}
+ ]}
+ ]}
+ );
+ },
+ createMonth: function() {
+ this.createComponent(
+ {kind: "onyx.PickerDecorator", onSelect: "updateMonth", components: [
+ {classes:"onyx-datepicker-month", name: "monthPickerButton", disabled: this.disabled},
+ {name: "monthPicker", kind: "onyx.Picker"}
+ ]}
+ );
+ },
+ createDay: function() {
+ this.createComponent(
+ {kind: "onyx.PickerDecorator", onSelect: "updateDay", components: [
+ {classes:"onyx-datepicker-day", name: "dayPickerButton", disabled: this.disabled},
+ {name: "dayPicker", kind: "onyx.Picker"}
+ ]}
+ );
+ },
+ localeChanged: function() {
+ this.refresh();
+ },
+ dayHiddenChanged: function() {
+ this.$.dayPicker.getParent().setShowing(this.dayHidden ? false : true);
+ },
+ monthHiddenChanged: function() {
+ this.$.monthPicker.getParent().setShowing(this.monthHidden ? false : true);
+ },
+ yearHiddenChanged: function() {
+ this.$.yearPicker.getParent().setShowing(this.yearHidden ? false : true);
+ },
+ minYearChanged: function() {
+ this.refresh();
+ },
+ maxYearChanged: function() {
+ this.refresh();
+ },
+ valueChanged: function(){
+ this.refresh();
+ },
+ disabledChanged: function() {
+ this.$.yearPickerButton.setDisabled(this.disabled);
+ this.$.monthPickerButton.setDisabled(this.disabled);
+ this.$.dayPickerButton.setDisabled(this.disabled);
+ },
+ updateDay: function(inSender, inEvent){
+ var date = this.calcDate(this.value.getFullYear(),
+ this.value.getMonth(),
+ inEvent.selected.value);
+ this.doSelect({name:this.name, value:date});
+ this.setValue(date);
+ return true;
+ },
+ updateMonth: function(inSender, inEvent){
+ var date = this.calcDate(this.value.getFullYear(),
+ inEvent.selected.value,
+ this.value.getDate());
+ this.doSelect({name:this.name, value:date});
+ this.setValue(date);
+ return true;
+ },
+ updateYear: function(inSender, inEvent){
+ //if the node wasn't found (issue around FlyWeightRepeater/Picker) don't update the picker
+ if (inEvent.originator.selected != -1) {
+ var date = this.calcDate(this.minYear + inEvent.originator.selected,
+ this.value.getMonth(),
+ this.value.getDate());
+ this.doSelect({name:this.name, value:date});
+ this.setValue(date);
+ }
+ return true;
+ },
+ calcDate: function(year, month, day){
+ return new Date(year,month,day,
+ this.value.getHours(),
+ this.value.getMinutes(),
+ this.value.getSeconds(),
+ this.value.getMilliseconds());
+ },
+ refresh: function(){
+ this.destroyClientControls();
+ this.initDefaults();
+ this.render();
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceDrawerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Drawer.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Drawer.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Drawer.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,115 @@
</span><ins>+/**
+ _onyx.Drawer_ is a control that appears or disappears based on its _open_
+ property. By default, the drawer appears or disappears with a sliding
+ animation whose direction is determined by the _orient_ property.
+
+ For more information, see the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Drawers">Drawers</a> in the
+ Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "onyx.Drawer",
+ published: {
+ //* The visibility state of the drawer's associated control
+ open: true,
+ /**
+ Direction of the opening/closing animation--either "v" for vertical
+ or "h" for horizontal
+ */
+ orient: "v",
+ //* If true, the opening/closing transition will be animated.
+ animated: true
+ },
+ //* @protected
+ style: "overflow: hidden; position: relative;",
+ tools: [
+ {kind: "Animator", onStep: "animatorStep", onEnd: "animatorEnd"},
+ {name: "client", style: "position: relative;", classes: "enyo-border-box"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.animatedChanged();
+ this.openChanged();
+ },
+ initComponents: function() {
+ this.createChrome(this.tools);
+ this.inherited(arguments);
+ },
+ animatedChanged: function() {
+ if (!this.animated && this.hasNode() && this.$.animator.isAnimating()) {
+ this.$.animator.stop();
+ this.animatorEnd();
+ }
+ },
+ openChanged: function() {
+ this.$.client.show();
+ if (this.hasNode()) {
+ if (this.$.animator.isAnimating()) {
+ this.$.animator.reverse();
+ } else {
+ var v = this.orient == "v";
+ var d = v ? "height" : "width";
+ var p = v ? "top" : "left";
+ // unfixing the height/width is needed to properly
+ // measure the scrollHeight/Width DOM property, but
+ // can cause a momentary flash of content on some browsers
+ this.applyStyle(d, null);
+ var s = this.hasNode()[v ? "scrollHeight" : "scrollWidth"];
+ if (this.animated) {
+ this.$.animator.play({
+ startValue: this.open ? 0 : s,
+ endValue: this.open ? s : 0,
+ dimension: d,
+ position: p
+ });
+ } else {
+ // directly run last frame if not animating
+ this.animatorEnd();
+ }
+ }
+ } else {
+ this.$.client.setShowing(this.open);
+ }
+ },
+ animatorStep: function(inSender) {
+ // the actual drawer DOM node adjusts its height
+ if (this.hasNode()) {
+ var d = inSender.dimension;
+ this.node.style[d] = this.domStyles[d] = inSender.value + "px";
+ }
+ // while the client inside the drawer adjusts its position to move out of the visible area
+ var cn = this.$.client.hasNode();
+ if (cn) {
+ var p = inSender.position;
+ var o = (this.open ? inSender.endValue : inSender.startValue);
+ cn.style[p] = this.$.client.domStyles[p] = (inSender.value - o) + "px";
+ }
+ if (this.container) {
+ this.container.resized();
+ }
+ },
+ animatorEnd: function() {
+ if (!this.open) {
+ this.$.client.hide();
+ }
+ else {
+ // save changes to this.domCssText --> see ENYO-1561
+ this.$.client.domCssText = enyo.Control.domStylesToCssText(this.$.client.domStyles);
+ // at end of open animation, clean limit on height/width
+ var v = (this.orient == "v");
+ var d = v ? "height" : "width";
+ var p = v ? "top" : "left";
+ var cn = this.$.client.hasNode();
+ // clear out changes to container position & node dimension
+ if (cn) {
+ cn.style[p] = this.$.client.domStyles[p] = null;
+ }
+ if (this.node) {
+ this.node.style[d] = this.domStyles[d] = null;
+ }
+ }
+ if (this.container) {
+ this.container.resized();
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceFlyweightPickerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/FlyweightPicker.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/FlyweightPicker.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/FlyweightPicker.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,131 @@
</span><ins>+/**
+ _onyx.FlyweightPicker_, a subkind of <a href="#onyx.Picker">onyx.Picker</a>,
+ is a picker that employs the flyweight pattern. It is used to display a
+ large list of selectable items. As with
+ <a href="#enyo.FlyweightRepeater">enyo.FlyweightRepeater</a>,
+ the _onSetupItem_ event allows for customization of item rendering.
+
+ To initialize the FlyweightPicker to a particular value, call _setSelected_
+ with the index of the item you wish to select, and call _setContent_ with
+ the item that should be shown in the activator button.
+
+ FlyweightPicker will send an _onSelect_ event with a selected item's
+ information. This can be received by a client application to determine which
+ item was selected.
+
+ enyo.kind({
+ handlers: {
+ onSelect: "itemSelected"
+ },
+ components: [
+ {kind: "onyx.PickerDecorator", components: [
+ {},
+ {name: "yearPicker", kind: "onyx.FlyweightPicker", count: 200,
+ onSetupItem: "setupYear", components: [
+ {name: "year"}
+ ]
+ }
+ ]}
+ ],
+ create: function() {
+ var d = new Date();
+ var y = d.getYear();
+ this.$.yearPicker.setSelected(y);
+ this.$.year.setContent(1900+y);
+ },
+ setupYear: function(inSender, inEvent) {
+ this.$.year.setContent(1900+inEvent.index);
+ },
+ itemSelected: function(inSender, inEvent) {
+ enyo.log("Picker Item Selected: " + inEvent.selected.content);
+ }
+ })
+ */
+enyo.kind({
+ name: "onyx.FlyweightPicker",
+ kind: "onyx.Picker",
+ classes: "onyx-flyweight-picker",
+ published: {
+ //* How many rows to render
+ count: 0
+ },
+ events: {
+ /**
+ Fires when a row is being initialized. The _index_ property contains
+ the row index, while the _flyweight_ property contains the row
+ control, for decoration.
+ */
+ onSetupItem: "",
+ /**
+ Fires when an item is selected. The _content_ property contains the
+ content of the selected item, while the _selected_ property contains
+ its row index.
+ */
+ onSelect: ""
+ },
+ //* @protected
+ handlers: {
+ onSelect: "itemSelect"
+ },
+ components: [
+ {name: "scroller", kind: "enyo.Scroller", strategyKind: "TouchScrollStrategy", components: [
+ {name: "flyweight", kind: "FlyweightRepeater", noSelect: true, ontap: "itemTap"}
+ ]}
+ ],
+ scrollerName: "scroller",
+ initComponents: function() {
+ this.controlParentName = 'flyweight';
+ this.inherited(arguments);
+ //Force the flyweight's client control (MenuItem is default) to activate. This will
+ //result in a call to processActivatedItem which preps our picker selection logic.
+ //This is a workaround for changes caused by ENYO-1609 which resulted in ENYO-1611.
+ this.$.flyweight.$.client.children[0].setActive(true);
+ },
+ create: function() {
+ this.inherited(arguments);
+ this.countChanged();
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ this.selectedChanged();
+ },
+ scrollToSelected: function() {
+ var n = this.$.flyweight.fetchRowNode(this.selected);
+ this.getScroller().scrollToNode(n, !this.menuUp);
+ },
+ countChanged: function() {
+ this.$.flyweight.count = this.count;
+ },
+ processActivatedItem: function(inItem) {
+ this.item = inItem;
+ },
+ selectedChanged: function(inOld) {
+ if (!this.item) {
+ return;
+ }
+ if (inOld != null) {
+ this.item.removeClass("selected");
+ this.$.flyweight.renderRow(inOld);
+ }
+ var n;
+ if (this.selected != null) {
+ this.item.addClass("selected");
+ this.$.flyweight.renderRow(this.selected);
+ // need to remove the class from control to make sure it won't apply to other rows
+ this.item.removeClass("selected");
+ n = this.$.flyweight.fetchRowNode(this.selected);
+ }
+ this.doChange({selected: this.selected, content: n && n.textContent || this.item.content});
+ },
+ itemTap: function(inSender, inEvent) {
+ this.setSelected(inEvent.rowIndex);
+ //Send the select event that we want the client to receive.
+ this.doSelect({selected: this.item, content: this.item.content});
+ },
+ itemSelect: function(inSender, inEvent) {
+ //Block all select events that aren't coming from this control. This is to prevent select events from MenuItems since they won't have the correct value in a Flyweight context.
+ if (inEvent.originator != this) {
+ return true;
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceGrabberjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Grabber.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Grabber.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Grabber.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+/**
+ A control styled to indicate that an object can be grabbed and moved. It
+ should only be used in this limited context--to indicate that dragging the
+ object will result in movement.
+
+ {kind: "onyx.Toolbar", components: [
+ {kind: "onyx.Grabber", ondragstart: "grabberDragstart",
+ ondrag: "grabberDrag", ondragfinish: "grabberDragFinish"},
+ {kind: "onyx.Button", content: "More stuff"}
+ ]}
+
+ When using a Grabber inside a Fittable control, be sure to set "noStretch: true"
+ on the Fittable or else give it an explicit height. Otherwise, the Grabber
+ may not be visible.
+*/
+enyo.kind({
+ name: "onyx.Grabber",
+ classes: "onyx-grabber"
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceGroupboxjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Groupbox.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Groupbox.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Groupbox.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+/**
+ _onyx.Groupbox_ displays rows of controls as a vertically-stacked group. It
+ is designed to have container controls as its children, with each container
+ representing a row in the Groupbox.
+
+ A header may be added by specifying an
+ <a href="#onyx.GroupboxHeader">onyx.GroupboxHeader</a> as the first control
+ in the Groupbox, e.g.:
+
+ {kind: "onyx.Groupbox", components: [
+ {kind: "onyx.GroupboxHeader", content: "Sounds"},
+ {components: [
+ {content: "System Sounds"},
+ {kind: "onyx.ToggleButton", value: true}
+ ]},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input"}
+ ]}
+ ]}
+ ]}
+
+*/
+enyo.kind({
+ name: "onyx.Groupbox",
+ classes: "onyx-groupbox"
+});
+
+/**
+ A GroupboxHeader is designed to be placed inside an <a href="#onyx.Groupbox">onyx.Groupbox</a>. When a header for a group is desired,
+ make a GroupboxHeader the first control inside a Groupbox.
+
+ {kind: "onyx.Groupbox", components: [
+ {kind: "onyx.GroupboxHeader", content: "Sounds"},
+ {content: "Yawn"},
+ {content: "Beep"}
+ ]}
+*/
+enyo.kind({
+ name: "onyx.GroupboxHeader",
+ classes: "onyx-groupbox-header"
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceIconjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Icon.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Icon.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Icon.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+/**
+ A control that displays an icon. The icon image is specified by setting the
+ *src* property to a URL.
+
+ In Onyx, icons have a size of 32x32 pixels. Since the icon image is applied
+ as a CSS background, the height and width of an icon must be set if an image
+ of a different size is used.
+
+ {kind: "onyx.Icon", src: "images/search.png"}
+
+ When an icon should act like a button, use an <a href="#onyx.IconButton">onyx.IconButton</a>.
+
+*/
+enyo.kind({
+ name: "onyx.Icon",
+ published: {
+ //* URL specifying path to icon image
+ src: "",
+ //* When true, icon is shown as disabled.
+ disabled: false
+ },
+ classes: "onyx-icon",
+ //* @protected
+ create: function() {
+ this.inherited(arguments);
+ if (this.src) {
+ this.srcChanged();
+ }
+ this.disabledChanged();
+ },
+ disabledChanged: function() {
+ this.addRemoveClass("disabled", this.disabled);
+ },
+ srcChanged: function() {
+ this.applyStyle("background-image", "url(" + enyo.path.rewrite(this.src) + ")");
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceIconButtonjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/IconButton.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/IconButton.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/IconButton.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+/**
+ _onyx.IconButton_ is an icon that acts like a button. The icon image is
+ specified by setting the _src_ property to a URL.
+
+ If you want to combine an icon with text inside a button, use an
+ <a href="#onyx.Icon">onyx.Icon</a> inside an
+ <a href="#onyx.Button">onyx.Button</a>.
+
+ The image associated with the _src_ property of the IconButton is assumed
+ to be 32x64-pixel strip with the top half showing the button's normal state
+ and the bottom half showing its state when hovered-over or active.
+
+ For more information, see the documentation on
+ [Buttons](https://github.com/enyojs/enyo/wiki/Buttons) in the Enyo Developer
+ Guide.
+*/
+enyo.kind({
+ name: "onyx.IconButton",
+ kind: "onyx.Icon",
+ published: {
+ //* Used when the IconButton is part of a <a href="#enyo.Group">enyo.Group</a>, true
+ //* to indicate that this is the active button of the group, false otherwise.
+ active: false
+ },
+ classes: "onyx-icon-button",
+ //* @protected
+ create: function() {
+ //workaround for FirefoxOS which doesn't support :active:hover css selectors
+ if(enyo.platform.firefoxOS) {
+ this.handlers.ondown = "down";
+ this.handlers.onleave = "leave";
+ }
+ this.inherited(arguments);
+ },
+ down: function(inSender, inEvent) {
+ this.addClass("pressed");
+ },
+ leave: function(inSender, inEvent) {
+ this.removeClass("pressed");
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ this.activeChanged();
+ },
+ tap: function() {
+ if (this.disabled) {
+ return true;
+ }
+ this.setActive(true);
+ },
+ activeChanged: function() {
+ this.bubble("onActivate");
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceInputjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Input.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Input.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Input.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+/**
+ _onyx.Input_ is an Onyx-styled input control, derived from
+ <a href="#enyo.Input">enyo.Input</a>. Typically, an _onyx.Input_ is placed
+ inside an <a href="#onyx.InputDecorator">onyx.InputDecorator</a>, which
+ provides styling, e.g.:
+
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "Enter some text...", onchange: "inputChange"}
+ ]}
+
+ For more information, see the documentation on
+ [Text Fields](https://github.com/enyojs/enyo/wiki/Text-Fields) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "onyx.Input",
+ kind: "enyo.Input",
+ classes: "onyx-input"
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceInputDecoratorjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/InputDecorator.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/InputDecorator.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/InputDecorator.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,61 @@
</span><ins>+/**
+ _onyx.InputDecorator_ is a control that provides input styling. Any controls
+ in the InputDecorator will appear to be inside an area styled as an input.
+ Usually, an InputDecorator surrounds an <a href="#onyx.Input">onyx.Input</a>.
+
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input"}
+ ]}
+
+ Other controls, such as buttons, may be placed to the right or left of the
+ input control, e.g.:
+
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.IconButton", src: "search.png"},
+ {kind: "onyx.Input"},
+ {kind: "onyx.IconButton", src: "cancel.png"}
+ ]}
+
+ Note that the InputDecorator fits around the content inside it. If the
+ decorator is sized, then its contents will likely need to be sized as well.
+
+ {kind: "onyx.InputDecorator", style: "width: 500px;", components: [
+ {kind: "onyx.Input", style: "width: 100%;"}
+ ]}
+*/
+enyo.kind({
+ name: "onyx.InputDecorator",
+ kind: "enyo.ToolDecorator",
+ tag: "label",
+ classes: "onyx-input-decorator",
+ published:{
+ //* Set to true to make the input look focused when it's not.
+ alwaysLooksFocused:false
+ },
+ //* @protected
+ handlers: {
+ onDisabledChange: "disabledChange",
+ onfocus: "receiveFocus",
+ onblur: "receiveBlur"
+ },
+ create:function() {
+ this.inherited(arguments);
+ this.updateFocus(false);
+ },
+ alwaysLooksFocusedChanged:function(oldValue) {
+ this.updateFocus(this.focus);
+ },
+ updateFocus:function(focus) {
+ this.focused = focus;
+ this.addRemoveClass("onyx-focused", this.alwaysLooksFocused || this.focused);
+ },
+ receiveFocus: function() {
+ this.updateFocus(true);
+ },
+ receiveBlur: function() {
+ this.updateFocus(false);
+ },
+ disabledChange: function(inSender, inEvent) {
+ this.addRemoveClass("onyx-disabled", inEvent.originator.disabled);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceIntegerPickerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/IntegerPicker.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/IntegerPicker.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/IntegerPicker.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+/**
+ _onyx.IntegerPicker_, a subkind of <a href="#onyx.Picker">onyx.Picker</a>,
+ is used to display a list of integers that can be selected, ranging from
+ _min_ to _max_. It is meant to be used in conjunction with an
+ <a href="#onyx.PickerDecorator">onyx.PickerDecorator</a>. The decorator
+ loosely couples the picker with an
+ <a href="#onyx.PickerButton">onyx.PickerButton</a>--a button that, when
+ tapped, shows the picker. Once an item is selected, the list of items
+ closes, but the item stays selected and the PickerButton displays the choice
+ that was made.
+
+ To initialize the IntegerPicker to a particular value, set the _value_
+ property to the integer that should be selected.
+
+ {kind: "onyx.PickerDecorator", components: [
+ {}, //this uses the defaultKind property of PickerDecorator to inherit from PickerButton
+ {kind: "onyx.IntegerPicker", min: 0, max: 25, value: 5}
+ ]}
+
+ Each item in the list is an <a href="#onyx.MenuItem">onyx.MenuItem</a>, so
+ an application may listen for an _onSelect_ event with the item to determine
+ which picker item was selected.
+
+ For more information, see the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Pickers">Pickers</a> in the
+ Enyo Developer Guide.
+ */
+enyo.kind({
+ name: "onyx.IntegerPicker",
+ kind: "onyx.Picker",
+ published: {
+ value: 0,
+ min: 0,
+ max: 9
+ },
+ //* @protected
+ create: function() {
+ this.inherited(arguments);
+ this.rangeChanged();
+ },
+ minChanged: function() {
+ this.destroyClientControls();
+ this.rangeChanged();
+ this.render();
+ },
+ maxChanged: function() {
+ this.destroyClientControls();
+ this.rangeChanged();
+ this.render();
+ },
+ rangeChanged: function() {
+ for (var i=this.min; i<=this.max; i++) {
+ this.createComponent({content: i, active: (i===this.value) ? true : false});
+ }
+ },
+ valueChanged: function(inOld) {
+ var controls = this.getClientControls();
+ var len = controls.length;
+ // Validate our value
+ this.value = this.value >= this.min && this.value <= this.max ? this.value : this.min;
+ for (var i=0; i<len; i++) {
+ if (this.value === parseInt(controls[i].content)) {
+ this.setSelected(controls[i]);
+ break;
+ }
+ }
+ },
+ selectedChanged: function(inOld) {
+ if (inOld) {
+ inOld.removeClass("selected");
+ }
+ if (this.selected) {
+ this.selected.addClass("selected");
+ this.doChange({selected: this.selected, content: this.selected.content});
+ }
+ this.value = parseInt(this.selected.content);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceItemjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Item.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Item.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Item.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+/**
+ A control designed to display a group of stacked items, typically used in
+ lists. By default, items are highlighted when tapped. Set *tapHighlight* to
+ false to prevent the highlighting.
+
+ {kind: "onyx.Item", tapHighlight: false}
+*/
+enyo.kind({
+ name: "onyx.Item",
+ classes: "onyx-item",
+ //* When true, the item will automatically highlight (by application of the onyx-highlight
+ //* CSS class) when tapped. Set to false to disable this behavior.
+ tapHighlight: true,
+ //* @protected
+ handlers: {
+ onhold: "hold",
+ onrelease: "release"
+ },
+ //* @public
+ hold: function(inSender, inEvent) {
+ if (this.tapHighlight) {
+ onyx.Item.addRemoveFlyweightClass(this.controlParent || this, "onyx-highlight", true, inEvent);
+ }
+ },
+ release: function(inSender, inEvent) {
+ if (this.tapHighlight) {
+ onyx.Item.addRemoveFlyweightClass(this.controlParent || this, "onyx-highlight", false, inEvent);
+ }
+ },
+ //* @protected
+ statics: {
+ addRemoveFlyweightClass: function(inControl, inClass, inTrueToAdd, inEvent, inIndex) {
+ var flyweight = inEvent.flyweight;
+ if (flyweight) {
+ var index = inIndex !== undefined ? inIndex : inEvent.index;
+ flyweight.performOnRow(index, function() {
+ inControl.addRemoveClass(inClass, inTrueToAdd);
+ });
+ }
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceMenujs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Menu.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Menu.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Menu.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,193 @@
</span><ins>+/**
+ _onyx.Menu_ is a subkind of <a href="#onyx.Popup">onyx.Popup</a> that
+ displays a list of <a href="#onyx.MenuItem">onyx.MenuItem</a> objects and
+ looks like a popup menu. It is meant to be used in conjunction with an
+ <a href="#onyx.MenuDecorator">onyx.MenuDecorator</a>. The decorator couples
+ the menu with an activating control, which may be a button or any other
+ control with an _onActivate_ event. When the control is activated, the menu
+ shows itself in the correct position relative to the activator.
+
+ {kind: "onyx.MenuDecorator", components: [
+ {content: "Show menu"},
+ {kind: "onyx.Menu", components: [
+ {content: "1"},
+ {content: "2"},
+ {classes: "onyx-menu-divider"},
+ {content: "Label", classes: "onyx-menu-label"},
+ {content: "3"},
+ ]}
+ ]}
+
+ For more information, see the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Menus">Menus</a> in the Enyo
+ Developer Guide.
+ */
+enyo.kind({
+ name: "onyx.Menu",
+ kind: "onyx.Popup",
+ //* If true, prevents controls outside the menu from receiving events while
+ //* the menu is showing
+ modal: true,
+ defaultKind: "onyx.MenuItem",
+ classes: "onyx-menu",
+ published: {
+ //* Maximum height of the menu
+ maxHeight: 200,
+ //* Toggle scrolling
+ scrolling: true
+ },
+ handlers: {
+ onActivate: "itemActivated",
+ onRequestShowMenu: "requestMenuShow",
+ onRequestHideMenu: "requestHide"
+ },
+ childComponents: [
+ {name: "client", kind: "enyo.Scroller", strategyKind: "TouchScrollStrategy"}
+ ],
+ showOnTop: false,
+ scrollerName: "client",
+ create: function() {
+ this.inherited(arguments);
+ this.maxHeightChanged();
+ },
+ initComponents: function() {
+ if (this.scrolling) {
+ this.createComponents(this.childComponents, {isChrome: true});
+ }
+ this.inherited(arguments);
+ },
+ getScroller: function() {
+ return this.$[this.scrollerName];
+ },
+ maxHeightChanged: function() {
+ if (this.scrolling) {
+ this.getScroller().setMaxHeight(this.maxHeight + "px");
+ }
+ },
+ itemActivated: function(inSender, inEvent) {
+ inEvent.originator.setActive(false);
+ return true;
+ },
+ showingChanged: function() {
+ this.inherited(arguments);
+ if (this.scrolling) {
+ this.getScroller().setShowing(this.showing);
+ }
+ this.adjustPosition(true);
+ },
+ requestMenuShow: function(inSender, inEvent) {
+ if (this.floating) {
+ var n = inEvent.activator.hasNode();
+ if (n) {
+ var r = this.activatorOffset = this.getPageOffset(n);
+ this.applyPosition({top: r.top + (this.showOnTop ? 0 : r.height), left: r.left, width: r.width});
+ }
+ }
+ this.show();
+ return true;
+ },
+ applyPosition: function(inRect) {
+ var s = "";
+ for (var n in inRect) {
+ s += (n + ":" + inRect[n] + (isNaN(inRect[n]) ? "; " : "px; "));
+ }
+ this.addStyles(s);
+ },
+ getPageOffset: function(inNode) {
+ // getBoundingClientRect returns top/left values which are relative to the viewport and not absolute
+ var r = inNode.getBoundingClientRect();
+
+ // IE8 doesn't return window.page{X/Y}Offset & r.{height/width}
+ // FIXME: Perhaps use an alternate universal method instead of conditionals
+ var pageYOffset = (window.pageYOffset === undefined) ? document.documentElement.scrollTop : window.pageYOffset;
+ var pageXOffset = (window.pageXOffset === undefined) ? document.documentElement.scrollLeft : window.pageXOffset;
+ var rHeight = (r.height === undefined) ? (r.bottom - r.top) : r.height;
+ var rWidth = (r.width === undefined) ? (r.right - r.left) : r.width;
+
+ return {top: r.top + pageYOffset, left: r.left + pageXOffset, height: rHeight, width: rWidth};
+ },
+ //* @protected
+ /* Adjusts the menu position to fit inside the current window size.
+ /* Note that we aren't currently adjusting picker scroller heights.
+ */
+ adjustPosition: function() {
+ if (this.showing && this.hasNode()) {
+ if (this.scrolling && !this.showOnTop) {
+ this.getScroller().setMaxHeight(this.maxHeight+"px");
+ }
+ this.removeClass("onyx-menu-up");
+
+ //reset the left position before we get the bounding rect for proper horizontal calculation
+ if (!this.floating) {
+ this.applyPosition({left: "auto"});
+ }
+
+ var b = this.node.getBoundingClientRect();
+ var bHeight = (b.height === undefined) ? (b.bottom - b.top) : b.height;
+ var innerHeight = (window.innerHeight === undefined) ? document.documentElement.clientHeight : window.innerHeight;
+ var innerWidth = (window.innerWidth === undefined) ? document.documentElement.clientWidth : window.innerWidth;
+
+ //position the menu above the activator if it's getting cut off, but only if there's more room above than below
+ this.menuUp = (b.top + bHeight > innerHeight) && ((innerHeight - b.bottom) < (b.top - bHeight));
+ this.addRemoveClass("onyx-menu-up", this.menuUp);
+
+ //if floating, adjust the vertical positioning
+ if (this.floating) {
+ var r = this.activatorOffset;
+ //if the menu doesn't fit below the activator, move it up
+ if (this.menuUp) {
+ this.applyPosition({top: (r.top - bHeight + (this.showOnTop ? r.height : 0)), bottom: "auto"});
+ }
+ else {
+ //if the top of the menu is above the top of the activator and there's room to move it down, do so
+ if ((b.top < r.top) && (r.top + (this.showOnTop ? 0 : r.height) + bHeight < innerHeight))
+ {
+ this.applyPosition({top: r.top + (this.showOnTop ? 0 : r.height), bottom: "auto"});
+ }
+ }
+ }
+
+ //adjust the horizontal positioning to keep the menu from being cut off on the right
+ if ((b.right) > innerWidth) {
+ if (this.floating){
+ this.applyPosition({left:innerWidth-b.width});
+ } else {
+ this.applyPosition({left: -(b.right - innerWidth)});
+ }
+ }
+
+ //finally prevent the menu from being cut off on the left
+ if (b.left < 0) {
+ if (this.floating){
+ this.applyPosition({left: 0, right:"auto"});
+ } else {
+ //handle the situation where a non-floating menu is right or left aligned
+ if (this.getComputedStyleValue("right") == "auto"){
+ this.applyPosition({left:-b.left});
+ } else {
+ this.applyPosition({right:b.left});
+ }
+ }
+ }
+
+ //adjust the scroller height based on room available - only doing this for menus currently
+ if (this.scrolling && !this.showOnTop){
+ b = this.node.getBoundingClientRect(); //update to the current menu position
+ var scrollerHeight;
+ if (this.menuUp){
+ scrollerHeight = (this.maxHeight < b.bottom) ? this.maxHeight : b.bottom;
+ } else {
+ scrollerHeight = ((b.top + this.maxHeight) < innerHeight) ? this.maxHeight : (innerHeight - b.top);
+ }
+ this.getScroller().setMaxHeight(scrollerHeight+"px");
+ }
+ }
+ },
+ resizeHandler: function() {
+ this.inherited(arguments);
+ this.adjustPosition();
+ },
+ requestHide: function(){
+ this.setShowing(false);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceMenuDecoratorjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/MenuDecorator.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/MenuDecorator.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/MenuDecorator.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,62 @@
</span><ins>+/**
+ A control that activates an <a href="#onyx.Menu">onyx.Menu</a>. It loosely
+ couples the Menu with an activating control, which may be a button or any
+ other control with an _onActivate_ event. The decorator must surround both
+ the activating control and the menu itself. When the control is activated,
+ the menu shows itself in the correct position relative to the activator.
+
+ {kind: "onyx.MenuDecorator", components: [
+ {content: "Show menu"},
+ {kind: "onyx.Menu", components: [
+ {content: "1"},
+ {content: "2"},
+ {classes: "onyx-menu-divider"},
+ {content: "Label", classes: "onyx-menu-label"},
+ {content: "3"},
+ ]}
+ ]}
+ */
+enyo.kind({
+ name: "onyx.MenuDecorator",
+ kind: "onyx.TooltipDecorator",
+ defaultKind: "onyx.Button",
+ // selection on ios prevents tap events, so avoid.
+ classes: "onyx-popup-decorator enyo-unselectable",
+ //* @protected
+ handlers: {
+ onActivate: "activated",
+ onHide: "menuHidden"
+ },
+ activated: function(inSender, inEvent) {
+ this.requestHideTooltip();
+ if (inEvent.originator.active) {
+ this.menuActive = true;
+ this.activator = inEvent.originator;
+ this.activator.addClass("active");
+ this.requestShowMenu();
+ }
+ },
+ requestShowMenu: function() {
+ this.waterfallDown("onRequestShowMenu", {activator: this.activator});
+ },
+ requestHideMenu: function() {
+ this.waterfallDown("onRequestHideMenu");
+ },
+ menuHidden: function() {
+ this.menuActive = false;
+ if (this.activator) {
+ this.activator.setActive(false);
+ this.activator.removeClass("active");
+ }
+ },
+ enter: function(inSender) {
+ if (!this.menuActive) {
+ this.inherited(arguments);
+ }
+ },
+ leave: function(inSender, inEvent) {
+ if (!this.menuActive) {
+ this.inherited(arguments);
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceMenuItemjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/MenuItem.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/MenuItem.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/MenuItem.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+/**
+ _MenuItem_ is a button styled to look like a menu item, intended for use in
+ an <a href="#onyx.Menu">onyx.Menu</a>. When the MenuItem is tapped, it
+ tells the menu to hide itself and sends an _onSelect_ event with its
+ content and a reference to itself. This event and its properties may be
+ received by a client application to determine which menu item was selected.
+
+ enyo.kind({
+ handlers: {
+ onSelect: "itemSelected"
+ },
+ components: [
+ {kind: "onyx.MenuDecorator", components: [
+ {content: "Open Menu (floating)"},
+ {kind: "onyx.Menu", floating: true, components: [
+ {content: "1"},
+ {content: "2"},
+ {classes: "onyx-menu-divider"},
+ {content: "Label", classes: "onyx-menu-label"},
+ {content: "3"},
+ ]}
+ ]}
+ ],
+ itemSelected: function(inSender, inEvent) {
+ enyo.log("Menu Item Selected: " + inEvent.originator.content);
+ }
+ })
+ */
+enyo.kind({
+ name: "onyx.MenuItem",
+ kind: "enyo.Button",
+ events: {
+ /**
+ Fires when the menu item is selected.
+
+ _inEvent.selected_ contains a reference to the menu item.
+
+ _inEvent.content_ contains the menu item's content.
+ */
+ onSelect: "",
+ /**
+ Fires when the content of an item changes.
+
+ _inEvent.content_ contains the content of the item.
+ */
+ onItemContentChange: ""
+ },
+ //* @protected
+ classes: "onyx-menu-item",
+ tag: "div",
+ create: function(){
+ this.inherited(arguments);
+ if (this.active){
+ this.bubble("onActivate");
+ }
+ },
+ tap: function(inSender) {
+ this.inherited(arguments);
+ this.bubble("onRequestHideMenu");
+ this.doSelect({selected:this, content:this.content});
+ },
+ contentChanged: function(inOld){
+ this.inherited(arguments);
+ this.doItemContentChange({content: this.content});
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceMoreToolbarjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/MoreToolbar.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/MoreToolbar.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/MoreToolbar.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,156 @@
</span><ins>+/**
+ _onyx.MoreToolbar_ extends <a href="#enyo.Control">enyo.Control</a>,
+ providing a toolbar that can adapt to different screen sizes by moving
+ overflowing controls and content into an <a href="#onyx.Menu">onyx.Menu</a>.
+
+ {kind: "onyx.MoreToolbar", components: [
+ {content: "More Toolbar", unmoveable: true},
+ {kind: "onyx.Button", content: "Alpha"},
+ {kind: "onyx.Button", content: "Beta"},
+ {kind: "onyx.Button", content: "Gamma", unmoveable: true},
+ {kind: "onyx.Button", content: "Epsilon"}
+ ]},
+
+ You may prevent a control from being moved into the menu by setting its
+ _unmoveable_ property to true (the default is false).
+
+ For more information, see the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Toolbars">Toolbars</a> in the
+ Enyo Developer Guide.
+*/
+
+enyo.kind({
+ name: "onyx.MoreToolbar",
+ //* @public
+ classes: "onyx-toolbar onyx-more-toolbar",
+ //* Style class to be applied to the menu
+ menuClass: "",
+ //* Style class to be applied to individual controls moved from the toolbar to the menu
+ movedClass: "",
+ //* @protected
+ layoutKind: "FittableColumnsLayout",
+ noStretch: true,
+ handlers: {
+ onHide: "reflow"
+ },
+ published: {
+ //* Layout kind that will be applied to the client controls.
+ clientLayoutKind: "FittableColumnsLayout"
+ },
+ tools: [
+ {name: "client", noStretch:true, fit: true, classes: "onyx-toolbar-inline"},
+ {name: "nard", kind: "onyx.MenuDecorator", showing: false, onActivate: "activated", components: [
+ {kind: "onyx.IconButton", classes: "onyx-more-button"},
+ {name: "menu", kind: "onyx.Menu", scrolling:false, classes: "onyx-more-menu"}
+ ]}
+ ],
+ initComponents: function() {
+ if(this.menuClass && this.menuClass.length>0 && !this.$.menu.hasClass(this.menuClass)) {
+ this.$.menu.addClass(this.menuClass);
+ }
+ this.createChrome(this.tools);
+ this.inherited(arguments);
+ this.$.client.setLayoutKind(this.clientLayoutKind);
+ },
+ clientLayoutKindChanged: function(){
+ this.$.client.setLayoutKind(this.clientLayoutKind);
+ },
+ reflow: function() {
+ this.inherited(arguments);
+ if (this.isContentOverflowing()) {
+ this.$.nard.show();
+ if (this.popItem()) {
+ this.reflow();
+ }
+ } else if (this.tryPushItem()) {
+ this.reflow();
+ } else if (!this.$.menu.children.length) {
+ this.$.nard.hide();
+ this.$.menu.hide();
+ }
+ },
+ activated: function(inSender, inEvent) {
+ this.addRemoveClass("active",inEvent.originator.active);
+ },
+ popItem: function() {
+ var c = this.findCollapsibleItem();
+ if (c) {
+ //apply movedClass is needed
+ if(this.movedClass && this.movedClass.length>0 && !c.hasClass(this.movedClass)) {
+ c.addClass(this.movedClass);
+ }
+ // passing null to add child to the front of the control list
+ this.$.menu.addChild(c, null);
+ var p = this.$.menu.hasNode();
+ if (p && c.hasNode()) {
+ c.insertNodeInParent(p);
+ }
+ return true;
+ }
+ },
+ pushItem: function() {
+ var c$ = this.$.menu.children;
+ var c = c$[0];
+ if (c) {
+ //remove any applied movedClass
+ if(this.movedClass && this.movedClass.length>0 && c.hasClass(this.movedClass)) {
+ c.removeClass(this.movedClass);
+ }
+ this.$.client.addChild(c);
+ var p = this.$.client.hasNode();
+ if (p && c.hasNode()) {
+ var nextChild;
+ var currIndex;
+ for(var i=0; i<this.$.client.children.length; i++) {
+ var curr = this.$.client.children[i];
+ if(curr.toolbarIndex !== undefined && curr.toolbarIndex != i) {
+ nextChild = curr;
+ currIndex = i;
+ break;
+ }
+ }
+ if(nextChild && nextChild.hasNode()) {
+ c.insertNodeInParent(p, nextChild.node);
+ var newChild = this.$.client.children.pop();
+ this.$.client.children.splice(currIndex, 0, newChild);
+ } else {
+ c.appendNodeToParent(p);
+ }
+ }
+ return true;
+ }
+ },
+ tryPushItem: function() {
+ if (this.pushItem()) {
+ if (!this.isContentOverflowing()) {
+ return true;
+ } else {
+ this.popItem();
+ }
+ }
+ },
+ isContentOverflowing: function() {
+ if (this.$.client.hasNode()) {
+ var c$ = this.$.client.children;
+ var n = c$[c$.length-1].hasNode();
+ if(n) {
+ this.$.client.reflow();
+ //Workaround: scrollWidth value not working in Firefox, so manually compute
+ //return (this.$.client.node.scrollWidth > this.$.client.node.clientWidth);
+ return ((n.offsetLeft + n.offsetWidth) > this.$.client.node.clientWidth);
+ }
+ }
+ },
+ findCollapsibleItem: function() {
+ var c$ = this.$.client.children;
+ for (var i=c$.length-1; (c=c$[i]); i--) {
+ if (!c.unmoveable) {
+ return c;
+ } else {
+ if(c.toolbarIndex===undefined) {
+ c.toolbarIndex = i;
+ }
+ }
+ }
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourcePickerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Picker.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Picker.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Picker.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,103 @@
</span><ins>+/**
+ _onyx.Picker_, a subkind of <a href="#onyx.Menu">onyx.Menu</a>, is used to
+ display a list of items that can be selected. It is meant to be used in
+ conjunction with an <a href="#onyx.PickerDecorator">onyx.PickerDecorator</a>.
+ The decorator loosely couples the picker with an
+ <a href="#onyx.PickerButton">onyx.PickerButton</a>--a button that, when
+ tapped, shows the picker. Once an item is selected, the list of items closes,
+ but the item stays selected and the PickerButton displays the choice that
+ was made.
+
+ To initialize the Picker to a particular value, set the _active_ property to
+ true for the item that should be selected.
+
+ {kind: "onyx.PickerDecorator", components: [
+ {}, //this uses the defaultKind property of PickerDecorator to inherit from PickerButton
+ {kind: "onyx.Picker", components: [
+ {content: "Gmail", active: true},
+ {content: "Yahoo"},
+ {content: "Outlook"},
+ {content: "Hotmail"}
+ ]}
+ ]}
+
+ Each item in the list is an <a href="#onyx.MenuItem">onyx.MenuItem</a>, so
+ an _onSelect_ event with the item can be listened to by a client application
+ to determine which picker item was selected.
+
+ For more information, see the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Pickers">Pickers</a> in the
+ Enyo Developer Guide.
+ */
+enyo.kind({
+ name: "onyx.Picker",
+ kind: "onyx.Menu",
+ classes: "onyx-picker enyo-unselectable",
+ published: {
+ //* Currently selected item, if any
+ selected: null
+ },
+ events: {
+ /**
+ Fires when the currently selected item changes.
+
+ _inEvent.selected_ contains the currently selected item.
+
+ _inEvent.content_ contains the content of the currently selected item.
+ */
+ onChange: ""
+ },
+ handlers: {
+ onItemContentChange: 'itemContentChange'
+ },
+ /**
+ Set to true to render the picker in a floating layer outside of other
+ controls. This can be used to guarantee that the picker will be shown
+ on top of other controls.
+ */
+ floating: true,
+ //* @protected
+ // overrides default value from onyx.Menu
+ showOnTop: true,
+ initComponents: function() {
+ this.setScrolling(true);
+ this.inherited(arguments);
+ },
+ showingChanged: function() {
+ this.getScroller().setShowing(this.showing);
+ this.inherited(arguments);
+ if (this.showing && this.selected) {
+ this.scrollToSelected();
+ }
+ },
+ scrollToSelected: function() {
+ this.getScroller().scrollToControl(this.selected, !this.menuUp);
+ },
+ itemActivated: function(inSender, inEvent) {
+ this.processActivatedItem(inEvent.originator);
+ return this.inherited(arguments);
+ },
+ processActivatedItem: function(inItem) {
+ if (inItem.active) {
+ this.setSelected(inItem);
+ }
+ },
+ selectedChanged: function(inOld) {
+ if (inOld) {
+ inOld.removeClass("selected");
+ }
+ if (this.selected) {
+ this.selected.addClass("selected");
+ this.doChange({selected: this.selected, content: this.selected.content});
+ }
+ },
+ itemContentChange: function(inSender, inEvent){
+ if(inEvent.originator == this.selected){
+ this.doChange({selected: this.selected, content: this.selected.content});
+ }
+ },
+ resizeHandler: function() {
+ this.inherited(arguments);
+ this.adjustPosition();
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourcePickerButtonjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/PickerButton.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/PickerButton.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/PickerButton.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+/**
+ _onyx.PickerButton_ is a button that, when tapped, shows an
+ <a href="#onyx.Picker">onyx.Picker</a>. Once an item is selected, the list
+ of items closes, but the item stays selected and the PickerButton displays
+ the choice that was made.
+
+ For more information, see the documentation on
+ [Pickers](https://github.com/enyojs/enyo/wiki/Pickers) in the Enyo Developer
+ Guide.
+ */
+enyo.kind({
+ name: "onyx.PickerButton",
+ kind: "onyx.Button",
+ handlers: {
+ onChange: "change"
+ },
+ change: function(inSender, inEvent) {
+ if (inEvent.content !== undefined){
+ this.setContent(inEvent.content);
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourcePickerDecoratorjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/PickerDecorator.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/PickerDecorator.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/PickerDecorator.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+/**
+ A control that activates an <a href="#onyx.Picker">onyx.Picker</a>. It
+ loosely couples the Picker with an activating
+ <a href="#onyx.PickerButton">onyx.PickerButton</a>. The decorator must
+ surround both the activating button and the picker itself. When the button
+ is activated, the picker shows itself in the correct position relative to
+ the activator.
+
+ {kind: "onyx.PickerDecorator", components: [
+ {}, //this uses the defaultKind property of PickerDecorator to inherit from PickerButton
+ {kind: "onyx.Picker", components: [
+ {content: "Gmail", active: true},
+ {content: "Yahoo"},
+ {content: "Outlook"},
+ {content: "Hotmail"}
+ ]}
+ ]}
+ */
+enyo.kind({
+ name: "onyx.PickerDecorator",
+ kind: "onyx.MenuDecorator",
+ classes: "onyx-picker-decorator",
+ defaultKind: "onyx.PickerButton",
+ handlers: {
+ onChange: "change"
+ },
+ change: function(inSender, inEvent) {
+ this.waterfallDown("onChange", inEvent);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourcePopupjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Popup.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Popup.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Popup.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,93 @@
</span><ins>+/**
+ _onyx.Popup_ is an enhanced [enyo.Popup](http://enyojs.com/api/#enyo.Popup)
+ with built-in scrim and z-index handling.
+
+ To avoid obscuring popup contents, scrims require the dialog to be floating;
+ otherwise, they won't render. A modal popup will get a transparent scrim
+ unless the popup isn't floating. To get a translucent scrim when modal,
+ specify _scrim: true, scrimWhenModal: false_.
+
+ For more information, see the documentation on
+ [Popups](https://github.com/enyojs/enyo/wiki/Popups) in the Enyo Developer
+ Guide.
+*/
+enyo.kind({
+ name: "onyx.Popup",
+ kind: "Popup",
+ classes: "onyx-popup",
+ published: {
+ /**
+ Determines whether a scrim will appear when the dialog is modal.
+ Note that modal scrims are transparent, so you won't see them.
+ */
+ scrimWhenModal: true,
+ //* Determines whether or not to display a scrim. Only displays scrims
+ //* when floating.
+ scrim: false,
+ /**
+ Optional class name to apply to the scrim. Be aware that the scrim
+ is a singleton and you will be modifying the scrim instance used for
+ other popups.
+ */
+ scrimClassName: ""
+ },
+ //* @protected
+ statics: { count: 0 },
+ defaultZ: 120,
+ showingChanged: function() {
+ if(this.showing) {
+ onyx.Popup.count++;
+ this.applyZIndex();
+ }
+ else {
+ if(onyx.Popup.count > 0) {
+ onyx.Popup.count--;
+ }
+ }
+ this.showHideScrim(this.showing);
+ this.inherited(arguments);
+ },
+ showHideScrim: function(inShow) {
+ if (this.floating && (this.scrim || (this.modal && this.scrimWhenModal))) {
+ var scrim = this.getScrim();
+ if (inShow) {
+ // move scrim to just under the popup to obscure rest of screen
+ var i = this.getScrimZIndex();
+ this._scrimZ = i;
+ scrim.showAtZIndex(i);
+ } else {
+ scrim.hideAtZIndex(this._scrimZ);
+ }
+ enyo.call(scrim, "addRemoveClass", [this.scrimClassName, scrim.showing]);
+ }
+ },
+ getScrimZIndex: function() {
+ // Position scrim directly below popup
+ return this.findZIndex()-1;
+ },
+ getScrim: function() {
+ // show a transparent scrim for modal popups if scrimWhenModal is true
+ // if scrim is true, then show a regular scrim.
+ if (this.modal && this.scrimWhenModal && !this.scrim) {
+ return onyx.scrimTransparent.make();
+ }
+ return onyx.scrim.make();
+ },
+ applyZIndex: function() {
+ // Adjust the zIndex so that popups will properly stack on each other.
+ this._zIndex = onyx.Popup.count * 2 + this.findZIndex() + 1;
+ // leave room for scrim
+ this.applyStyle("z-index", this._zIndex);
+ },
+ findZIndex: function() {
+ // a default z value
+ var z = this.defaultZ;
+ if (this._zIndex) {
+ z = this._zIndex;
+ } else if (this.hasNode()) {
+ // Re-use existing zIndex if it has one
+ z = Number(enyo.dom.getComputedStyleValue(this.node, "z-index")) || z;
+ }
+ return (this._zIndex = z);
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceProgressBarjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/ProgressBar.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/ProgressBar.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/ProgressBar.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,104 @@
</span><ins>+/**
+ _onyx.ProgressBar_ is a control that shows the current progress of a
+ process in a horizontal bar.
+
+ {kind: "onyx.ProgressBar", progress: 10}
+
+ To animate progress changes, call the _animateProgressTo_ method:
+
+ this.$.progressBar.animateProgressTo(50);
+
+ You may customize the color of the bar by applying a style via the
+ _barClasses_ property, e.g.:
+
+ {kind: "onyx.ProgressBar", barClasses: "onyx-dark"}
+
+ For more information, see the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Progress-Indicators">Progress Indicators</a>
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "onyx.ProgressBar",
+ classes: "onyx-progress-bar",
+ published: {
+ //* Current position of progress bar
+ progress: 0,
+ //* Minimum progress value (i.e., no progress made)
+ min: 0,
+ //* Maximum progress value (i.e., process complete)
+ max: 100,
+ //* CSS classes to apply to progress bar
+ barClasses: "",
+ //* If true, stripes are shown in progress bar
+ showStripes: true,
+ //* If true (and _showStripes_ is true), stripes shown in progress bar
+ //* are animated
+ animateStripes: true,
+ //* Value increment that a sliders can be "snapped to" in either direction
+ increment: 0
+ },
+ events: {
+ //* Fires when progress bar finishes animating to a position.
+ onAnimateProgressFinish: ""
+ },
+ //* @protected
+ components: [
+ {name: "progressAnimator", kind: "Animator", onStep: "progressAnimatorStep", onEnd: "progressAnimatorComplete"},
+ {name: "bar", classes: "onyx-progress-bar-bar"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.progressChanged();
+ this.barClassesChanged();
+ this.showStripesChanged();
+ this.animateStripesChanged();
+ },
+ barClassesChanged: function(inOld) {
+ this.$.bar.removeClass(inOld);
+ this.$.bar.addClass(this.barClasses);
+ },
+ showStripesChanged: function() {
+ this.$.bar.addRemoveClass("striped", this.showStripes);
+ },
+ animateStripesChanged: function() {
+ this.$.bar.addRemoveClass("animated", this.animateStripes);
+ },
+ progressChanged: function() {
+ this.progress = this.clampValue(this.min, this.max, this.progress);
+ var p = this.calcPercent(this.progress);
+ this.updateBarPosition(p);
+ },
+ calcIncrement: function(inValue) {
+ return (Math.round(inValue / this.increment) * this.increment);
+ },
+ clampValue: function(inMin, inMax, inValue) {
+ return Math.max(inMin, Math.min(inValue, inMax));
+ },
+ calcRatio: function(inValue) {
+ return (inValue - this.min) / (this.max - this.min);
+ },
+ calcPercent: function(inValue) {
+ return this.calcRatio(inValue) * 100;
+ },
+ updateBarPosition: function(inPercent) {
+ this.$.bar.applyStyle("width", inPercent + "%");
+ },
+ //* @public
+ //* Animates progress to the given value.
+ animateProgressTo: function(inValue) {
+ this.$.progressAnimator.play({
+ startValue: this.progress,
+ endValue: inValue,
+ node: this.hasNode()
+ });
+ },
+ //* @protected
+ progressAnimatorStep: function(inSender) {
+ this.setProgress(inSender.value);
+ return true;
+ },
+ progressAnimatorComplete: function(inSender) {
+ this.doAnimateProgressFinish(inSender);
+ return true;
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceProgressButtonjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/ProgressButton.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/ProgressButton.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/ProgressButton.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+/**
+ _onyx.ProgressButton_ is a progress bar that has a cancel button on the
+ right and may have other controls inside of it.
+
+ {kind: "onyx.ProgressButton"},
+ {kind: "onyx.ProgressButton", barClasses: "onyx-light", progress: 20, components: [
+ {content: "0"},
+ {content: "100", style: "float: right;"}
+ ]}
+
+ For more information, see the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Progress-Indicators">Progress Indicators</a>
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "onyx.ProgressButton",
+ kind: "onyx.ProgressBar",
+ classes: "onyx-progress-button",
+ events: {
+ //* Fires when cancel button is tapped.
+ onCancel: ""
+ },
+ //* @protected
+ components: [
+ {name: "progressAnimator", kind: "Animator", onStep: "progressAnimatorStep", onEnd: "progressAnimatorComplete"},
+ {name: "bar", classes: "onyx-progress-bar-bar onyx-progress-button-bar"},
+ {name: "client", classes: "onyx-progress-button-client"},
+ {kind: "onyx.Icon", src: "$lib/onyx/images/progress-button-cancel.png", classes: "onyx-progress-button-icon", ontap: "cancelTap"}
+ ],
+ cancelTap: function() {
+ this.doCancel();
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceRadioButtonjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/RadioButton.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/RadioButton.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/RadioButton.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+/**
+ A radio button designed for use within an
+ <a href="#onyx.RadioGroup">onyx.RadioGroup</a>.
+
+ For more information, see the documentation on
+ [Buttons](https://github.com/enyojs/enyo/wiki/Buttons) in the Enyo Developer
+ Guide.
+*/
+enyo.kind({
+ name: "onyx.RadioButton",
+ kind: "Button",
+ classes: "onyx-radiobutton"
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceRadioGroupjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/RadioGroup.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/RadioGroup.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/RadioGroup.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+/**
+ A group of <a href="#onyx.RadioButton">onyx.RadioButton</a> objects
+ laid out horizontally. Within the same radio group, tapping on one radio button
+ will release any previously tapped radio button.
+
+ {kind: "onyx.RadioGroup", components: [
+ {content: "foo", active: true},
+ {content: "bar"},
+ {content: "baz"}
+ ]}
+*/
+enyo.kind({
+ name: "onyx.RadioGroup",
+ kind: "Group",
+ defaultKind: "onyx.RadioButton",
+ //* @protected
+ // set to true to provide radio button behavior
+ highlander: true
+});
+
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceRangeSliderjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/RangeSlider.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/RangeSlider.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/RangeSlider.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,227 @@
</span><ins>+/**
+ _onyx.RangeSlider_ is a control that combines a horizontal slider with two
+ control knobs. The user may drag the knobs to select a desired range of
+ values.
+
+ {kind: "onyx.RangeSlider", rangeMin: 100, rangeMax: 500,
+ rangeStart: 200, rangeEnd: 400, interval: 20}
+
+ _onChanging_ events are fired while the control knobs are being dragged, and
+ an _onChange_ event is fired when the position is set by finishing a drag.
+*/
+enyo.kind({
+ name: "onyx.RangeSlider",
+ kind: "onyx.ProgressBar",
+ classes: "onyx-slider",
+ published: {
+ //* @public
+ //* Minimum slider value
+ rangeMin: 0,
+ //* Maximum slider value
+ rangeMax: 100,
+ /**
+ Value of first slider, expressed as an integer between _rangeMin_
+ and _rangeMax_
+ */
+ rangeStart: 0,
+ /**
+ Value of second slider, expressed as an integer between _rangeMin_
+ and _rangeMax_
+ */
+ rangeEnd: 100,
+ //* @protected
+ // Position of first slider, expressed as an integer between 0 and 100 (percentage)
+ beginValue: 0,
+ // Position of second slider, expressed as an integer between 0 and 100 (percentage)
+ endValue: 0
+ },
+ //* @public
+ events: {
+ /**
+ Fires when bar position is set.
+
+ _inEvent.value_ contains the new position.
+
+ _inEvent.startChanged_ is a boolean value indicating whether the
+ first slider (_rangeStart_) triggered the event.
+ */
+ onChange: "",
+ /**
+ Fires while control knob is being dragged.
+
+ _inEvent.value_ contains the current position.
+ */
+ onChanging: ""
+ },
+ //* If true, stripes are shown in the slider bar
+ showStripes: false,
+ //* If true, labels are shown above each slider knob
+ showLabels: false,
+ //* @protected
+ handlers: {
+ ondragstart: "dragstart",
+ ondrag: "drag",
+ ondragfinish: "dragfinish",
+ ondown: "down"
+ },
+ moreComponents: [
+ {name: "startKnob", classes: "onyx-slider-knob"},
+ {name: "endKnob", classes: "onyx-slider-knob onyx-range-slider-knob"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.createComponents(this.moreComponents);
+ this.initControls();
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ var p = this.calcPercent(this.beginValue);
+ this.updateBarPosition(p);
+ },
+ initControls: function() {
+ this.$.bar.applyStyle("position", "relative");
+ this.refreshRangeSlider();
+ if (this.showLabels) {
+ this.$.startKnob.createComponent({name: "startLabel", kind: "onyx.RangeSliderKnobLabel"});
+ this.$.endKnob.createComponent({name: "endLabel", kind: "onyx.RangeSliderKnobLabel"});
+ }
+ },
+ refreshRangeSlider: function() {
+ // Calculate range percentages, in order to position sliders
+ this.beginValue = this.calcKnobPercent(this.rangeStart);
+ this.endValue = this.calcKnobPercent(this.rangeEnd);
+ this.beginValueChanged();
+ this.endValueChanged();
+ },
+ calcKnobRatio: function(inValue) {
+ return (inValue - this.rangeMin) / (this.rangeMax - this.rangeMin);
+ },
+ calcKnobPercent: function(inValue) {
+ return this.calcKnobRatio(inValue) * 100;
+ },
+ beginValueChanged: function(sliderPos) {
+ if (sliderPos === undefined) {
+ var p = this.calcPercent(this.beginValue);
+ this.updateKnobPosition(p, this.$.startKnob);
+ }
+ },
+ endValueChanged: function(sliderPos) {
+ if (sliderPos === undefined) {
+ var p = this.calcPercent(this.endValue);
+ this.updateKnobPosition(p, this.$.endKnob);
+ }
+ },
+ calcKnobPosition: function(inEvent) {
+ var x = inEvent.clientX - this.hasNode().getBoundingClientRect().left;
+ return (x / this.getBounds().width) * (this.max - this.min) + this.min;
+ },
+ updateKnobPosition: function(inPercent, inControl) {
+ inControl.applyStyle("left", inPercent + "%");
+ this.updateBarPosition();
+ },
+ updateBarPosition: function() {
+ if ((this.$.startKnob !== undefined) && (this.$.endKnob !== undefined)) {
+ var barStart = this.calcKnobPercent(this.rangeStart);
+ var barWidth = this.calcKnobPercent(this.rangeEnd) - barStart;
+ this.$.bar.applyStyle("left", barStart + "%");
+ this.$.bar.applyStyle("width", barWidth + "%");
+ }
+ },
+ calcRangeRatio: function(inValue) {
+ return ((inValue / 100) * (this.rangeMax - this.rangeMin) + this.rangeMin) - (this.increment/2);
+ },
+ swapZIndex: function(inControl) {
+ if (inControl === "startKnob") {
+ this.$.startKnob.applyStyle("z-index", 1);
+ this.$.endKnob.applyStyle("z-index", 0);
+ } else if (inControl === "endKnob") {
+ this.$.startKnob.applyStyle("z-index", 0);
+ this.$.endKnob.applyStyle("z-index", 1);
+ }
+ },
+ down: function(inSender, inEvent) {
+ this.swapZIndex(inSender.name);
+ },
+ dragstart: function(inSender, inEvent) {
+ if (inEvent.horizontal) {
+ inEvent.preventDefault();
+ this.dragging = true;
+ return true;
+ }
+ },
+ drag: function(inSender, inEvent) {
+ if (this.dragging) {
+ var knobPos = this.calcKnobPosition(inEvent);
+ var _val, val, p;
+
+ if ((inSender.name === "startKnob") && (knobPos >= 0)) {
+ if (((knobPos <= this.endValue) && (inEvent.xDirection === -1)) || (knobPos <= this.endValue)) {
+ this.setBeginValue(knobPos);
+ _val = this.calcRangeRatio(this.beginValue);
+ val = (this.increment) ? this.calcIncrement(_val+0.5*this.increment) : _val;
+ p = this.calcKnobPercent(val);
+ this.updateKnobPosition(p, this.$.startKnob);
+ this.setRangeStart(val);
+ this.doChanging({value: val});
+ } else {
+ return this.drag(this.$.endKnob, inEvent);
+ }
+ } else if ((inSender.name === "endKnob") && (knobPos <= 100)) {
+ if (((knobPos >= this.beginValue) && (inEvent.xDirection === 1)) || (knobPos >= this.beginValue)) {
+ this.setEndValue(knobPos);
+ _val = this.calcRangeRatio(this.endValue);
+ val = (this.increment) ? this.calcIncrement(_val+0.5*this.increment) : _val;
+ p = this.calcKnobPercent(val);
+ this.updateKnobPosition(p, this.$.endKnob);
+ this.setRangeEnd(val);
+ this.doChanging({value: val});
+ } else {
+ return this.drag(this.$.startKnob, inEvent);
+ }
+ }
+ return true;
+ }
+ },
+ dragfinish: function(inSender, inEvent) {
+ this.dragging = false;
+ inEvent.preventTap();
+ var val;
+ if (inSender.name === "startKnob") {
+ val = this.calcRangeRatio(this.beginValue);
+ this.doChange({value: val, startChanged: true});
+ } else if (inSender.name === "endKnob") {
+ val = this.calcRangeRatio(this.endValue);
+ this.doChange({value: val, startChanged: false});
+ }
+ return true;
+ },
+ rangeMinChanged: function() {
+ this.refreshRangeSlider();
+ },
+ rangeMaxChanged: function() {
+ this.refreshRangeSlider();
+ },
+ rangeStartChanged: function() {
+ this.refreshRangeSlider();
+ },
+ rangeEndChanged: function() {
+ this.refreshRangeSlider();
+ },
+ setStartLabel: function(inContent) {
+ this.$.startKnob.waterfallDown("onSetLabel", inContent);
+ },
+ setEndLabel: function(inContent) {
+ this.$.endKnob.waterfallDown("onSetLabel", inContent);
+ }
+});
+
+enyo.kind({
+ name: "onyx.RangeSliderKnobLabel",
+ classes: "onyx-range-slider-label",
+ handlers: {
+ onSetLabel: "setLabel"
+ },
+ setLabel: function(inSender, inContent) {
+ this.setContent(inContent);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceRichTextjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/RichText.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/RichText.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/RichText.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+/**
+ _onyx.RichText_ is an Onyx-styled RichText control, derived from
+ <a href="#enyo.RichText">enyo.RichText</a>. Typically, an _onyx.RichText_
+ is placed inside an <a href="#onyx.InputDecorator">onyx.InputDecorator</a>,
+ which provides styling, e.g.:
+
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.RichText", style: "width: 100px;", onchange: "inputChange"}
+ ]}
+
+ For more information, see the documentation on
+ [Text Fields](https://github.com/enyojs/enyo/wiki/Text-Fields) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "onyx.RichText",
+ kind: "enyo.RichText",
+ classes: "onyx-richtext"
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceScrimjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Scrim.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Scrim.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Scrim.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,114 @@
</span><ins>+/**
+ _onyx.Scrim_ provides an overlay that will prevent taps from propagating to
+ the controls that it covers. A scrim may be "floating" or "non-floating". A
+ floating scrim will fill the entire viewport, while a non-floating scrim
+ will be constrained by the dimensions of its container.
+
+ The scrim should have a CSS class of _"onyx-scrim-transparent"_,
+ _"onyx-scrim-translucent"_, or any other class that has
+ _"pointer-events: auto"_ in its style properties.
+
+ You may specify the z-index at which you want the scrim to appear by calling
+ _showAtZIndex_; if you do so, you must call _hideAtZIndex_ with the same
+ value to hide the scrim.
+*/
+
+enyo.kind({
+ name: "onyx.Scrim",
+ //* Current visibility state of scrim
+ showing: false,
+ classes: "onyx-scrim enyo-fit",
+ /**
+ If true, scrim is rendered in a floating layer outside of other
+ controls. This can be used to guarantee that the scrim will be shown
+ on top of other controls.
+ */
+ floating: false,
+ //* @protected
+ create: function() {
+ this.inherited(arguments);
+ this.zStack = [];
+ if (this.floating) {
+ this.setParent(enyo.floatingLayer);
+ }
+ },
+ showingChanged: function() {
+ // auto render when shown.
+ if (this.floating && this.showing && !this.hasNode()) {
+ this.render();
+ }
+ this.inherited(arguments);
+ //this.addRemoveClass(this.showingClassName, this.showing);
+ },
+ //* @protected
+ addZIndex: function(inZIndex) {
+ if (enyo.indexOf(inZIndex, this.zStack) < 0) {
+ this.zStack.push(inZIndex);
+ }
+ },
+ removeZIndex: function(inControl) {
+ enyo.remove(inControl, this.zStack);
+ },
+ //* @public
+ //* Shows scrim at the specified z-index. Note: If you use _showAtZIndex_,
+ //* you must call _hideAtZIndex_ to properly unwind the z-index stack.
+ showAtZIndex: function(inZIndex) {
+ this.addZIndex(inZIndex);
+ if (inZIndex !== undefined) {
+ this.setZIndex(inZIndex);
+ }
+ this.show();
+ },
+ //* Hides scrim at the specified z-index.
+ hideAtZIndex: function(inZIndex) {
+ this.removeZIndex(inZIndex);
+ if (!this.zStack.length) {
+ this.hide();
+ } else {
+ var z = this.zStack[this.zStack.length-1];
+ this.setZIndex(z);
+ }
+ },
+ //* @protected
+ // Set scrim to show at `inZIndex`
+ setZIndex: function(inZIndex) {
+ this.zIndex = inZIndex;
+ this.applyStyle("z-index", inZIndex);
+ },
+ make: function() {
+ return this;
+ }
+});
+
+//* @protected
+//
+// Scrim singleton exposing a subset of Scrim API;
+// is replaced with a proper enyo.Scrim instance.
+//
+enyo.kind({
+ name: "onyx.scrimSingleton",
+ kind: null,
+ constructor: function(inName, inProps) {
+ this.instanceName = inName;
+ enyo.setObject(this.instanceName, this);
+ this.props = inProps || {};
+ },
+ make: function() {
+ var s = new onyx.Scrim(this.props);
+ enyo.setObject(this.instanceName, s);
+ return s;
+ },
+ showAtZIndex: function(inZIndex) {
+ var s = this.make();
+ s.showAtZIndex(inZIndex);
+ },
+ // in case somebody does this out of order
+ hideAtZIndex: enyo.nop,
+ show: function() {
+ var s = this.make();
+ s.show();
+ }
+});
+
+new onyx.scrimSingleton("onyx.scrim", {floating: true, classes: "onyx-scrim-translucent"});
+new onyx.scrimSingleton("onyx.scrimTransparent", {floating: true, classes: "onyx-scrim-transparent"});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceSliderjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Slider.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Slider.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Slider.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,136 @@
</span><ins>+/**
+ _onyx.Slider_ is a control that presents a range of selection options in the
+ form of a horizontal slider with a control knob. The knob may be tapped and
+ dragged to the desired location.
+
+ {kind: "onyx.Slider", value: 30}
+
+ _onChanging_ events are fired while the control knob is being dragged, and
+ an _onChange_ event is fired when the position is set, either by finishing a
+ drag or by tapping the bar.
+
+ For more information, see the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Progress-Indicators">Progress Indicators</a>
+ in the Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "onyx.Slider",
+ kind: "onyx.ProgressBar",
+ classes: "onyx-slider",
+ published: {
+ //* Position of slider, expressed as an integer between 0 and 100,
+ //* inclusive
+ value: 0,
+ //* If true, current progress will be styled differently from rest of bar
+ lockBar: true,
+ //* If true, tapping on bar will change current position
+ tappable: true
+ },
+ events: {
+ //* Fires when bar position is set. The _value_ property contains the
+ //* new position.
+ onChange: "",
+ //* Fires while control knob is being dragged. The _value_ property
+ //* contains the current position.
+ onChanging: "",
+ //* Fires when animation to a position finishes.
+ onAnimateFinish: ""
+ },
+ //* If true, stripes are shown in the slider bar
+ showStripes: false,
+ //* @protected
+ handlers: {
+ ondragstart: "dragstart",
+ ondrag: "drag",
+ ondragfinish: "dragfinish"
+ },
+ moreComponents: [
+ {kind: "Animator", onStep: "animatorStep", onEnd: "animatorComplete"},
+ {classes: "onyx-slider-taparea"},
+ {name: "knob", classes: "onyx-slider-knob"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ //workaround for FirefoxOS which doesn't support :active:hover css selectors
+ if(enyo.platform.firefoxOS) {
+ this.moreComponents[2].ondown = "down";
+ this.moreComponents[2].onleave = "leave";
+ }
+ this.createComponents(this.moreComponents);
+ this.valueChanged();
+ },
+ valueChanged: function() {
+ this.value = this.clampValue(this.min, this.max, this.value);
+ var p = this.calcPercent(this.value);
+ this.updateKnobPosition(p);
+ if (this.lockBar) {
+ this.setProgress(this.value);
+ }
+ },
+ updateKnobPosition: function(inPercent) {
+ this.$.knob.applyStyle("left", inPercent + "%");
+ },
+ calcKnobPosition: function(inEvent) {
+ var x = inEvent.clientX - this.hasNode().getBoundingClientRect().left;
+ return (x / this.getBounds().width) * (this.max - this.min) + this.min;
+ },
+ dragstart: function(inSender, inEvent) {
+ if (inEvent.horizontal) {
+ inEvent.preventDefault();
+ this.dragging = true;
+ return true;
+ }
+ },
+ drag: function(inSender, inEvent) {
+ if (this.dragging) {
+ var v = this.calcKnobPosition(inEvent);
+ v = (this.increment) ? this.calcIncrement(v) : v;
+ this.setValue(v);
+ this.doChanging({value: this.value});
+ return true;
+ }
+ },
+ dragfinish: function(inSender, inEvent) {
+ this.dragging = false;
+ inEvent.preventTap();
+ this.doChange({value: this.value});
+ return true;
+ },
+ tap: function(inSender, inEvent) {
+ if (this.tappable) {
+ var v = this.calcKnobPosition(inEvent);
+ v = (this.increment) ? this.calcIncrement(v) : v;
+ this.tapped = true;
+ this.animateTo(v);
+ return true;
+ }
+ },
+ down: function(inSender, inEvent) {
+ this.addClass("pressed");
+ },
+ leave: function(inSender, inEvent) {
+ this.removeClass("pressed");
+ },
+ //* @public
+ //* Animates to the given value.
+ animateTo: function(inValue) {
+ this.$.animator.play({
+ startValue: this.value,
+ endValue: inValue,
+ node: this.hasNode()
+ });
+ },
+ //* @protected
+ animatorStep: function(inSender) {
+ this.setValue(inSender.value);
+ return true;
+ },
+ animatorComplete: function(inSender) {
+ if (this.tapped) {
+ this.tapped = false;
+ this.doChange({value: this.value});
+ }
+ this.doAnimateFinish(inSender);
+ return true;
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceSpinnerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Spinner.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Spinner.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Spinner.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+/**
+ A control that displays a spinner animation to indicate that activity is
+ taking place. By default, onyx.Spinner will display a light spinner,
+ suitable for displaying against a dark background. To render a dark spinner
+ to be shown on a lighter background, add the "onyx-light" class to the
+ spinner:
+
+ {kind: "onyx.Spinner", classes: "onyx-light"}
+
+ Typically, a spinner is shown to indicate activity and hidden to indicate
+ that the activity has ended. The spinner animation will automatically start
+ when a spinner is shown. If you wish, you may control the animation directly
+ by calling the *start*, *stop*, and *toggle* methods.
+*/
+enyo.kind({
+ name: "onyx.Spinner",
+ classes: "onyx-spinner",
+ //* @public
+ //* Stops the spinner animation.
+ stop: function() {
+ this.setShowing(false);
+ },
+ //* Starts the spinner animation.
+ start: function() {
+ this.setShowing(true);
+ },
+ //* Toggles the spinner animation on or off.
+ toggle: function() {
+ this.setShowing(!this.getShowing());
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceTabPanelsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/TabPanels.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/TabPanels.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/TabPanels.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,128 @@
</span><ins>+/**
+enyo.TabPanels is a subkind of <a href="#enyo.Panels">enyo.Panels</a> that
+displays a set of tabs, which allow navigation between the individual panels.
+Unlike enyo.Panels, by default, the user cannot drag between the panels of a
+TabPanels. This behavior can be enabled by setting *draggable* to true.
+
+Here's an example:
+
+ enyo.kind({
+ name: "App",
+ kind: "TabPanels",
+ fit: true,
+ components: [
+ {kind: "MyStartPanel"},
+ {kind: "MyMiddlePanel"},
+ {kind: "MyLastPanel"}
+ ]
+ });
+ new App().write();
+*/
+enyo.kind({
+ name: "enyo.TabPanels",
+ kind: "Panels",
+ //* @protected
+ draggable: false,
+ tabTools: [
+ {name: "scroller", kind: "Scroller", maxHeight: "100px", strategyKind: "TranslateScrollStrategy", thumb: false, vertical: "hidden", horizontal: "auto", components: [
+ {name: "tabs", kind: "onyx.RadioGroup", style: "text-align: left; white-space: nowrap", controlClasses: "onyx-tabbutton", onActivate: "tabActivate"}
+ ]},
+ {name: "client", fit: true, kind: "Panels", classes: "enyo-tab-panels", onTransitionStart: "clientTransitionStart"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.$.client.getPanels = enyo.bind(this, "getClientPanels");
+ this.draggableChanged();
+ this.animateChanged();
+ this.wrapChanged();
+ },
+ initComponents: function() {
+ this.createChrome(this.tabTools);
+ this.inherited(arguments);
+ },
+ getClientPanels: function() {
+ return this.getPanels();
+ },
+ flow: function() {
+ this.inherited(arguments);
+ this.$.client.flow();
+ },
+ reflow: function() {
+ this.inherited(arguments);
+ this.$.client.reflow();
+ },
+ draggableChanged: function() {
+ this.$.client.setDraggable(this.draggable);
+ this.draggable = false;
+ },
+ animateChanged: function() {
+ this.$.client.setAnimate(this.animate);
+ this.animate = false;
+ },
+ wrapChanged: function() {
+ this.$.client.setWrap(this.wrap);
+ this.wrap = false;
+ },
+ isPanel: function(inControl) {
+ var n = inControl.name;
+ return !(n == "tabs" || n == "client" || n == "scroller");
+ },
+ addControl: function(inControl) {
+ this.inherited(arguments);
+ if (this.isPanel(inControl)) {
+ var c = inControl.caption || ("Tab " + this.$.tabs.controls.length);
+ var t = inControl._tab = this.$.tabs.createComponent({content: c});
+ if (this.hasNode()) {
+ t.render();
+ }
+ }
+ },
+ removeControl: function(inControl) {
+ if (this.isPanel(inControl) && inControl._tab) {
+ inControl._tab.destroy();
+ }
+ this.inherited(arguments);
+ },
+ layoutKindChanged: function() {
+ if (!this.layout) {
+ this.layout = enyo.createFromKind("FittableRowsLayout", this);
+ }
+ this.$.client.setLayoutKind(this.layoutKind);
+ },
+ indexChanged: function() {
+ // FIXME: initialization order problem
+ if (this.$.client.layout) {
+ this.$.client.setIndex(this.index);
+ }
+ this.index = this.$.client.getIndex();
+ },
+ tabActivate: function(inSender, inEvent) {
+ if (this.hasNode()) {
+ if (inEvent.originator.active) {
+ var i = inEvent.originator.indexInContainer();
+ if (this.getIndex() != i) {
+ this.setIndex(i);
+ }
+ }
+ }
+ },
+ clientTransitionStart: function(inSender, inEvent) {
+ var i = inEvent.toIndex;
+ var t = this.$.tabs.getClientControls()[i];
+ if (t && t.hasNode()) {
+ this.$.tabs.setActive(t);
+ var tn = t.node;
+ var tl = tn.offsetLeft;
+ var tr = tl + tn.offsetWidth;
+ var sb = this.$.scroller.getScrollBounds();
+ if (tr < sb.left || tr > sb.left + sb.clientWidth) {
+ this.$.scroller.scrollToControl(t);
+ }
+ }
+ return true;
+ },
+ startTransition: enyo.nop,
+ finishTransition: enyo.nop,
+ stepTransition: enyo.nop,
+ refresh: enyo.nop
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceTextAreajs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/TextArea.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/TextArea.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/TextArea.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+/**
+ _onyx.TextArea_ is an Onyx-styled TextArea control, derived from
+ <a href="#enyo.TextArea">enyo.TextArea</a>. Typically, an _onyx.TextArea_
+ is placed inside an <a href="#onyx.InputDecorator">onyx.InputDecorator</a>,
+ which provides styling, e.g.:
+
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.TextArea", onchange: "inputChange"}
+ ]}
+
+ For more information, see the documentation on
+ [Text Fields](https://github.com/enyojs/enyo/wiki/Text-Fields) in the Enyo
+ Developer Guide.
+*/
+enyo.kind({
+ name: "onyx.TextArea",
+ kind: "enyo.TextArea",
+ classes: "onyx-textarea"
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceTimePickerjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/TimePicker.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/TimePicker.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/TimePicker.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,210 @@
</span><ins>+/**
+ _onyx.TimePicker_ is a group of <a href="#onyx.Picker">onyx.Picker</a>
+ controls displaying the current time. The user may change the hour, minute,
+ and AM/PM values.
+
+ By default, _TimePicker_ tries to determine the current locale and use its
+ rules to format the time (including AM/PM). In order to do this
+ successfully, the _g11n_ library must be loaded; if it is not loaded, the
+ control defaults to using standard U.S. time format.
+ */
+enyo.kind({
+ name: "onyx.TimePicker",
+ classes: "onyx-toolbar-inline",
+ published: {
+ //* If true, control is shown as disabled, and user can't select new values
+ disabled: false,
+ /**
+ Current locale used for formatting. Can be set after control
+ creation, in which case the control will be updated to reflect the
+ new value.
+ */
+ locale: "en_us",
+ //* If true, 24-hour time is used. This is reset when locale is changed.
+ is24HrMode: null,
+ /**
+ The current Date object. When a Date object is passed to _setValue_,
+ the control is updated to reflect the new value. _getValue_ returns
+ a Date object.
+ */
+ value: null
+ },
+ events: {
+ /**
+ Fires when one of the TimePicker's fields is selected.
+
+ _inEvent.name_ contains the name of the TimePicker that generated
+ the event.
+
+ _inEvent.value_ contains the current Date value of the control.
+ */
+ onSelect: ""
+ },
+ create: function() {
+ this.inherited(arguments);
+ if (enyo.g11n) {
+ this.locale = enyo.g11n.currentLocale().getLocale();
+ }
+ this.initDefaults();
+ },
+ initDefaults: function() {
+ // defaults that match en_US for when g11n isn't loaded
+ var am = "AM", pm = "PM";
+ if (this.is24HrMode == null) {
+ this.is24HrMode = false;
+ }
+ // Attempt to use the g11n lib (ie assume it is loaded)
+ if (enyo.g11n) {
+ this._tf = new enyo.g11n.Fmts({locale:this.locale});
+ am = this._tf.getAmCaption();
+ pm = this._tf.getPmCaption();
+
+ if (this.is24HrMode == null) {
+ this.is24HrMode = !this._tf.isAmPm();
+ }
+ }
+
+ this.setupPickers(this._tf ? this._tf.getTimeFieldOrder() : 'hma');
+
+ var d = this.value = this.value || new Date();
+
+ // create hours
+ var i;
+ if (!this.is24HrMode){
+ var h = d.getHours();
+ h = (h === 0) ? 12 : h;
+ for (i=1; i<=12; i++) {
+ this.$.hourPicker.createComponent({content: i, value:i, active: (i == (h>12 ? h%12 : h))});
+ }
+ } else {
+ for (i=0; i<24; i++) {
+ this.$.hourPicker.createComponent({content: i, value:i, active: (i == d.getHours())});
+ }
+ }
+
+ // create minutes
+ for (i=0; i<=59; i++) {
+ this.$.minutePicker.createComponent({content: (i < 10) ? ("0"+i):i, value:i, active: i == d.getMinutes()});
+ }
+
+ // create am/pm
+ if (d.getHours() >= 12) {
+ this.$.ampmPicker.createComponents([{content: am},{content:pm, active: true}]);
+ }
+ else {
+ this.$.ampmPicker.createComponents([{content: am, active: true},{content:pm}]);
+ }
+ this.$.ampmPicker.getParent().setShowing(!this.is24HrMode);
+ },
+ setupPickers: function(ordering) {
+ var orderingArr = ordering.split("");
+ var o,f,l;
+ for(f = 0, l = orderingArr.length; f < l; f++) {
+ o = orderingArr[f];
+ switch (o){
+ case 'h': this.createHour();
+ break;
+ case 'm': this.createMinute();
+ break;
+ case 'a': this.createAmPm();
+ break;
+ default: break;
+ }
+ }
+ },
+ createHour: function() {
+ this.createComponent(
+ {kind: "onyx.PickerDecorator", onSelect: "updateHour", components: [
+ {classes:"onyx-timepicker-hour", name: "hourPickerButton", disabled: this.disabled},
+ {name: "hourPicker", kind: "onyx.Picker"}
+ ]}
+ );
+ },
+ createMinute: function() {
+ this.createComponent(
+ {kind: "onyx.PickerDecorator", onSelect: "updateMinute", components: [
+ {classes:"onyx-timepicker-minute", name: "minutePickerButton", disabled: this.disabled},
+ {name: "minutePicker", kind: "onyx.Picker"}
+ ]}
+ );
+ },
+ createAmPm: function() {
+ this.createComponent(
+ {kind: "onyx.PickerDecorator", onSelect: "updateAmPm", components: [
+ {classes:"onyx-timepicker-ampm", name: "ampmPickerButton", disabled: this.disabled},
+ {name: "ampmPicker", kind: "onyx.Picker"}
+ ]}
+ );
+ },
+ disabledChanged: function() {
+ this.$.hourPickerButton.setDisabled(this.disabled);
+ this.$.minutePickerButton.setDisabled(this.disabled);
+ this.$.ampmPickerButton.setDisabled(this.disabled);
+ },
+ localeChanged: function() {
+ //reset 24 hour mode when changing locales
+ this.is24HrMode = null;
+ this.refresh();
+ },
+ is24HrModeChanged: function() {
+ this.refresh();
+ },
+ valueChanged: function(){
+ this.refresh();
+ },
+ updateHour: function(inSender, inEvent){
+ var h = inEvent.selected.value;
+ if (!this.is24HrMode){
+ var ampm = this.$.ampmPicker.getParent().controlAtIndex(0).content;
+ h = h + (h == 12 ? -12 : 0) + (this.isAm(ampm) ? 0 : 12);
+ }
+ this.value = this.calcTime(h, this.value.getMinutes());
+ this.doSelect({name:this.name, value:this.value});
+ return true;
+ },
+ updateMinute: function(inSender, inEvent){
+ this.value = this.calcTime(this.value.getHours(), inEvent.selected.value);
+ this.doSelect({name:this.name, value:this.value});
+ return true;
+ },
+ updateAmPm: function(inSender, inEvent){
+ var h = this.value.getHours();
+ if (!this.is24HrMode){
+ h = h + (h > 11 ? (this.isAm(inEvent.content) ? -12 : 0) : (this.isAm(inEvent.content) ? 0 : 12));
+ }
+ this.value = this.calcTime(h, this.value.getMinutes());
+ this.doSelect({name:this.name, value:this.value});
+ return true;
+ },
+ calcTime: function(hour, minute){
+ return new Date(this.value.getFullYear(),
+ this.value.getMonth(),
+ this.value.getDate(),
+ hour, minute,
+ this.value.getSeconds(),
+ this.value.getMilliseconds());
+ },
+ isAm: function(value){
+ var am, pm, isAm;
+ //Workaround for pickers not having directly retrievable active item. Using it to find whether
+ //picker is on AM or PM (& have to check localized spelling as well)
+ try {
+ am = this._tf.getAmCaption();
+ pm = this._tf.getPmCaption();
+ } catch (err) {
+ am = "AM";
+ pm = "PM";
+ }
+
+ if (value == am){
+ return true;
+ } else {
+ return false;
+ }
+ },
+ refresh: function(){
+ this.destroyClientControls();
+ this.initDefaults();
+ this.render();
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceToggleButtonjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/ToggleButton.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/ToggleButton.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/ToggleButton.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,118 @@
</span><ins>+/**
+ _onyx.ToggleButton_ is a control that looks like a switch with labels for
+ two states. Each time a ToggleButton is tapped, it switches its value and
+ fires an _onChange_ event.
+
+ To get the value of the button, call _getValue_.
+
+ For more information, see the documentation on
+ [Buttons](https://github.com/enyojs/enyo/wiki/Buttons) in the Enyo Developer
+ Guide.
+*/
+enyo.kind({
+ name: "onyx.ToggleButton",
+ classes: "onyx-toggle-button",
+ published: {
+ //* Used when the ToggleButton is part of a <a href="#enyo.Group">enyo.Group</a>, true
+ //* to indicate that this is the active button of the group, false otherwise.
+ active: false,
+ //* Boolean indicating whether toggle button is currently in the "on"
+ //* state
+ value: false,
+ //* Label for toggle button's "on" state
+ onContent: "On",
+ //* Label for toggle button's "off" state
+ offContent: "Off",
+ //* If true, toggle button cannot be tapped and thus will not generate
+ //* any events
+ disabled: false
+ },
+ events: {
+ /**
+ Fires when the user changes the value of the toggle button, but not
+ when the value is changed programmatically.
+
+ _inEvent.value_ contains the value of the toggle button.
+ */
+ onChange: ""
+ },
+ //* @protected
+ handlers: {
+ ondragstart: "dragstart",
+ ondrag: "drag",
+ ondragfinish: "dragfinish"
+ },
+ components: [
+ {name: "contentOn", classes: "onyx-toggle-content on"},
+ {name: "contentOff", classes: "onyx-toggle-content off"},
+ {classes: "onyx-toggle-button-knob"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.value = Boolean(this.value || this.active);
+ this.onContentChanged();
+ this.offContentChanged();
+ this.disabledChanged();
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ this.updateVisualState();
+ },
+ updateVisualState: function() {
+ this.addRemoveClass("off", !this.value);
+ this.$.contentOn.setShowing(this.value);
+ this.$.contentOff.setShowing(!this.value);
+ this.setActive(this.value);
+ },
+ valueChanged: function() {
+ this.updateVisualState();
+ this.doChange({value: this.value});
+ },
+ activeChanged: function() {
+ this.setValue(this.active);
+ this.bubble("onActivate");
+ },
+ onContentChanged: function() {
+ this.$.contentOn.setContent(this.onContent || "");
+ this.$.contentOn.addRemoveClass("empty", !this.onContent);
+ },
+ offContentChanged: function() {
+ this.$.contentOff.setContent(this.offContent || "");
+ this.$.contentOff.addRemoveClass("empty", !this.onContent);
+ },
+ disabledChanged: function() {
+ this.addRemoveClass("disabled", this.disabled);
+ },
+ updateValue: function(inValue) {
+ if (!this.disabled) {
+ this.setValue(inValue);
+ }
+ },
+ tap: function() {
+ this.updateValue(!this.value);
+ },
+ dragstart: function(inSender, inEvent) {
+ if (inEvent.horizontal) {
+ inEvent.preventDefault();
+ this.dragging = true;
+ this.dragged = false;
+ return true;
+ }
+ },
+ drag: function(inSender, inEvent) {
+ if (this.dragging) {
+ var d = inEvent.dx;
+ if (Math.abs(d) > 10) {
+ this.updateValue(d > 0);
+ this.dragged = true;
+ }
+ return true;
+ }
+ },
+ dragfinish: function(inSender, inEvent) {
+ this.dragging = false;
+ if (this.dragged) {
+ inEvent.preventTap();
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceToggleIconButtonjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/ToggleIconButton.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/ToggleIconButton.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/ToggleIconButton.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,58 @@
</span><ins>+/**
+ _onyx.ToggleIconButton_ is an icon that acts like a toggle switch. The icon
+ image is specified by setting the _src_ property to a URL.
+
+ {kind: "onyx.ToggleIconButton", src: "images/search.png", ontap: "buttonTap"}
+
+ The image associated with the _src_ property is assumed to be a 32x64-pixel
+ strip, with the top half showing the button's normal state and the bottom
+ half showing its state when hovered-over or active.
+*/
+
+enyo.kind({
+ name: "onyx.ToggleIconButton",
+ kind: "onyx.Icon",
+ published: {
+ /**
+ Used when the ToggleIconButton is part of an enyo.Group; set to true
+ to indicate that this is the active button in the group.
+ */
+ active: false,
+ //* Boolean indicating whether the button is currently in the "on" state
+ value: false
+ },
+ events: {
+ /**
+ Fires when the user changes the value of the toggle button, but not
+ when the value is changed programmatically.
+ */
+ onChange: ""
+ },
+ classes: "onyx-icon-button onyx-icon-toggle",
+ //* @protected
+ activeChanged: function() {
+ this.addRemoveClass("active", this.value);
+ this.bubble("onActivate");
+ },
+ updateValue: function(inValue) {
+ if (!this.disabled) {
+ this.setValue(inValue);
+ this.doChange({value: this.value});
+ }
+ },
+ tap: function() {
+ this.updateValue(!this.value);
+ },
+ valueChanged: function() {
+ this.setActive(this.value);
+ },
+ create: function() {
+ this.inherited(arguments);
+ this.value = Boolean(this.value || this.active);
+ },
+ rendered: function() {
+ this.inherited(arguments);
+ this.valueChanged();
+ this.removeClass('onyx-icon');
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceToolbarjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Toolbar.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Toolbar.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Toolbar.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+/**
+ _onyx.Toolbar_ is a horizontal bar containing controls used to perform
+ common UI actions.
+
+ A Toolbar customizes the styling of the controls it hosts, including
+ buttons, icons, and inputs.
+
+ {kind: "onyx.Toolbar", components: [
+ {kind: "onyx.Button", content: "Favorites"},
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "Enter a search term..."}
+ ]},
+ {kind: "onyx.IconButton", src: "go.png"}
+ ]}
+
+ For more information, see the documentation on
+ <a href="https://github.com/enyojs/enyo/wiki/Toolbars">Toolbars</a> in the
+ Enyo Developer Guide.
+*/
+enyo.kind({
+ name: "onyx.Toolbar",
+ classes: "onyx onyx-toolbar onyx-toolbar-inline",
+ create: function(){
+ this.inherited(arguments);
+
+ //workaround for android 4.0.3 rendering glitch (ENYO-674)
+ if (this.hasClass('onyx-menu-toolbar') && (enyo.platform.android >= 4)){
+ this.applyStyle("position", "static");
+ }
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceTooltipjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/Tooltip.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/Tooltip.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/Tooltip.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,86 @@
</span><ins>+/**
+ _onyx.Tooltip_ is a kind of <a href="#onyx.Popup">onyx.Popup</a> that works
+ with an <a href="#onyx.TooltipDecorator">onyx.TooltipDecorator</a>. It
+ automatically displays a tooltip when the user hovers over the decorator.
+ The tooltip is positioned around the decorator where there is available
+ window space.
+
+ {kind: "onyx.TooltipDecorator", components: [
+ {kind: "onyx.Button", content: "Tooltip"},
+ {kind: "onyx.Tooltip", content: "I'm a tooltip for a button."}
+ ]}
+
+ You may manually display the tooltip by calling its _show_ method.
+*/
+enyo.kind({
+ name: "onyx.Tooltip",
+ kind: "onyx.Popup",
+ classes: "onyx-tooltip below left-arrow",
+ //* If true, tooltip is automatically dismissed when user stops hovering
+ //* over the decorator
+ autoDismiss: false,
+ //* Hovering over the decorator for this length of time (in milliseconds)
+ //* causes the tooltip to appear.
+ showDelay: 500,
+ //* Default margin-left value
+ defaultLeft: -6,
+ //* @protected
+ handlers: {
+ onRequestShowTooltip: "requestShow",
+ onRequestHideTooltip: "requestHide"
+ },
+ requestShow: function() {
+ this.showJob = setTimeout(enyo.bind(this, "show"), this.showDelay);
+ return true;
+ },
+ cancelShow: function() {
+ clearTimeout(this.showJob);
+ },
+ requestHide: function() {
+ this.cancelShow();
+ return this.inherited(arguments);
+ },
+ showingChanged: function() {
+ this.cancelShow();
+ this.adjustPosition(true);
+ this.inherited(arguments);
+ },
+ applyPosition: function(inRect) {
+ var s = "";
+ for (var n in inRect) {
+ s += (n + ":" + inRect[n] + (isNaN(inRect[n]) ? "; " : "px; "));
+ }
+ this.addStyles(s);
+ },
+ adjustPosition: function(belowActivator) {
+ if (this.showing && this.hasNode()) {
+ var b = this.node.getBoundingClientRect();
+
+ //when the tooltip bottom goes below the window height move it above the decorator
+ if (b.top + b.height > window.innerHeight) {
+ this.addRemoveClass("below", false);
+ this.addRemoveClass("above", true);
+ } else {
+ this.addRemoveClass("above", false);
+ this.addRemoveClass("below", true);
+ }
+
+ //when the tooltip's right edge is out of the window, align its right edge with the decorator left edge (approx)
+ if (b.left + b.width > window.innerWidth){
+ this.applyPosition({'margin-left': -b.width, bottom: "auto"});
+ //use the right-arrow
+ this.addRemoveClass("left-arrow", false);
+ this.addRemoveClass("right-arrow", true);
+ }
+ }
+ },
+ resizeHandler: function() {
+ //reset the tooltip to align its left edge with the decorator
+ this.applyPosition({'margin-left': this.defaultLeft, bottom: "auto"});
+ this.addRemoveClass("left-arrow", true);
+ this.addRemoveClass("right-arrow", false);
+
+ this.adjustPosition(true);
+ this.inherited(arguments);
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourceTooltipDecoratorjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/TooltipDecorator.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/TooltipDecorator.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/TooltipDecorator.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+/**
+ A control that activates an <a href="#onyx.Tooltip">onyx.Tooltip</a>. It
+ surrounds a control such as a button and displays the tooltip when the
+ control generates an _onEnter_ event:
+
+ {kind: "onyx.TooltipDecorator", components: [
+ {kind: "onyx.Button", content: "Tooltip"},
+ {kind: "onyx.Tooltip", content: "I'm a tooltip for a button."}
+ ]}
+
+ Here's an example with an <a href="#onyx.Input">onyx.Input</a> control and a
+ decorator around the input:
+
+ {kind: "onyx.TooltipDecorator", components: [
+ {kind: "onyx.InputDecorator", components: [
+ {kind: "onyx.Input", placeholder: "Just an input..."}
+ ]},
+ {kind: "onyx.Tooltip", content: "I'm a tooltip for an input."}
+ ]}
+*/
+enyo.kind({
+ name: "onyx.TooltipDecorator",
+ defaultKind: "onyx.Button",
+ //* @protected
+ classes: "onyx-popup-decorator",
+ handlers: {
+ onenter: "enter",
+ onleave: "leave"
+ },
+ enter: function() {
+ this.requestShowTooltip();
+ },
+ leave: function() {
+ this.requestHideTooltip();
+ },
+ tap: function() {
+ this.requestHideTooltip();
+ },
+ requestShowTooltip: function() {
+ this.waterfallDown("onRequestShowTooltip");
+ },
+ requestHideTooltip: function() {
+ this.waterfallDown("onRequestHideTooltip");
+ }
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourcedesignjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/design.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/design.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/design.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,168 @@
</span><ins>+//* @protected
+// Design description of the Onyx controls for use in the Ares designer tool.
+Palette.model.push(
+ {name: "onyx", items: [
+ {name: "onyx.Button", description: "A Pushbutton",
+ inline: {content: "onyx.Button", kind: "onyx.Button"},
+ config: {content: "$name", isContainer: true, kind: "onyx.Button"}
+ },
+ {name: "onyx.Checkbox", description: "A checkbox",
+ inline: {kind: "onyx.Checkbox"},
+ config: {kind: "onyx.Checkbox"}
+ },
+ {name: "onyx.DatePicker", description: "A control for choosing a date",
+ inline: {kind: "onyx.DatePicker"},
+ config: {kind: "onyx.DatePicker"}
+ },
+ {name: "onyx.Drawer", description: "A drawer that opens and closes",
+ inline: {kind: "onyx.Drawer"},
+ config: {kind: "onyx.Drawer"}
+ },
+ {name: "onyx.Groupbox", description: "A container for a group of controls",
+ inline: {kind: "onyx.Groupbox", components: [
+ {content: "Header", kind: "onyx.GroupboxHeader"},
+ {content: "Item", style: "padding: 10px;"}
+ ]},
+ config: {kind: "onyx.Groupbox", isContainer: true, components: [
+ {content: "Header", kind: "onyx.GroupboxHeader", isContainer: true},
+ {content: "Item", style: "padding: 10px;"}
+ ]}
+ },
+ {name: "onyx.GroupboxHeader", description: "A header for the Groupbox",
+ inline: {content: "Header", kind: "onyx.GroupboxHeader"},
+ config: {content: "$name", kind: "onyx.GroupboxHeader", isContainer: true}
+ },
+ {name: "onyx.Icon", description: "An Icon",
+ inline: {kind: "onyx.Icon"},
+ config: {kind: "onyx.Icon"}
+ },
+ {name: "onyx.IconButton", description: "An IconButton",
+ inline: {kind: "onyx.IconButton"},
+ config: {kind: "onyx.IconButton"}
+ },
+ {name: "onyx.InputDecorator", description: "Style an Input",
+ inline: {kind: "onyx.InputDecorator", components: [
+ {kind: "Input", placeholder: "Enter text here"}
+ ]},
+ config: {kind: "onyx.InputDecorator", components: [
+ {kind: "Input", placeholder: "Enter text here"}
+ ]}
+ },
+ {name: "onyx.Input", description: "Text input control",
+ inline: {value: "onyx.Input", kind: "onyx.Input"},
+ config: {kind: "onyx.Input"}
+ },
+ {name: "onyx.Item", description: "Stackable item, for lists and menus",
+ inline: {value: "onyx.Item", kind: "onyx.Item"},
+ config: {content: "$name", kind: "onyx.Item"}
+ },
+ {name: "onyx.MenuDecorator", description: "A Menu and activating control",
+ inline: {},
+ config: {kind: "onyx.MenuDecorator", components: [
+ {content: "Show menu"},
+ {kind: "onyx.Menu", components: [
+ {content: "1"},
+ {content: "2"},
+ {classes: "onyx-menu-divider"},
+ {content: "Label", classes: "onyx-menu-label"},
+ {content: "3"}
+ ]}
+ ]}
+ },
+ {name: "onyx.PickerDecorator", description: "A Picker and activating control",
+ inline: {},
+ config: {kind: "onyx.PickerDecorator", components: [
+ {content: "Pick1"}, //this uses the defaultKind property of PickerDecorator to inherit from PickerButton
+ {kind: "onyx.Picker", components: [
+ {content: "Pick1", active: true},
+ {content: "Pick2"},
+ {content: "Pick3"},
+ {content: "Pick4"}
+ ]}
+ ]}
+ },
+ {name: "onyx.ProgressBar", description: "A progress bar",
+ inline: {},
+ config: {kind: "onyx.ProgressBar"}
+ },
+ {name: "onyx.ProgressButton", description: "A progress button",
+ inline: {},
+ config: {kind: "onyx.ProgressButton"}
+ },
+ {name: "onyx.RadioGroup", description: "Only one control in a group can be 'active' at a time",
+ inline: {kind: "onyx.RadioGroup", components: [
+ {content: "A"},
+ {content: "B"},
+ {content: "C"}
+ ]},
+ config: {kind: "onyx.RadioGroup", isContainer: true, components: [
+ {content: "RadioButton"}
+ ]}
+ },
+ {name: "onyx.RadioButton", description: "An on-off button, for use with RadioGroup",
+ inline: {content: "RadioButton", kind: "onyx.RadioButton"},
+ config: {content: "$name", kind: "onyx.RadioButton"}
+ },
+ {name: "onyx.RangeSlider", description: "A Slider with two knobs",
+ inline: {value: "onyx.RangeSlider", kind: "onyx.RangeSlider"},
+ config: {kind: "onyx.RangeSlider"}
+ },
+ {name: "onyx.RichText", description: "A Rich text input",
+ inline: {value: "onyx.RichText", kind: "onyx.RichText"},
+ config: {kind: "onyx.RichText", style: "height: 100px"}
+ },
+ {name: "onyx.Slider", description: "A Slider",
+ inline: {value: "onyx.Slider", kind: "onyx.Slider"},
+ config: {kind: "onyx.Slider"}
+ },
+ {name: "onyx.Spinner", description: "A Spinner",
+ inline: {kind: "onyx.Spinner"},
+ config: {kind: "onyx.Spinner", classes: "onyx-light"}
+ },
+ {name: "onyx.TextArea", description: "A multi-line text input",
+ inline: {kind: "onyx.TextArea"},
+ config: {kind: "onyx.TextArea"}
+ },
+ {name: "onyx.TimePicker", description: "A Picker for time",
+ inline: {kind: "onyx.TimePicker"},
+ config: {kind: "onyx.TimePicker"}
+ },
+ {name: "onyx.ToggleButton", description: "A pushbutton that toggles between active and inactive states",
+ inline: {kind: "onyx.ToggleButton"},
+ config: {kind: "onyx.ToggleButton"}
+ },
+ {name: "onyx.ToggleIconButton", description: "A ToggleButton that toggles between active and inactive images",
+ inline: {kind: "onyx.ToggleIconButton"},
+ config: {kind: "onyx.ToggleIconButton"}
+ },
+ {name: "onyx.Toolbar", description: "A toolbar",
+ inline: {kind: "onyx.Toolbar"},
+ config: {isContainer: true, kind: "onyx.Toolbar"}
+ },
+ {name: "onyx.MoreToolbar", description: "A toolbar which adapts to screen width ",
+ inline: {kind: "onyx.Toolbar"},
+ config: {isContainer: true, kind: "onyx.MoreToolbar", components: [
+ {content: "MoreToolbar"},
+ {kind: "onyx.Item", content: "Resize Me!"},
+ {kind: "onyx.Button", content: "this"},
+ {kind: "onyx.Button", content: "toolbar"},
+ {kind: "onyx.Button", content: "has"},
+ {kind: "onyx.Button", content: "many"},
+ {kind: "onyx.Button", content: "items"},
+ {kind: "onyx.Button", content: "in"},
+ {kind: "onyx.Button", content: "it"}
+ ]}
+ },
+ {name: "onyx.Grabber", description: "Graphical 'handle' for dragging",
+ inline: {kind: "onyx.Grabber", style: "background-color: #333; padding: 4px 12px;"},
+ config: {kind: "onyx.Grabber"}
+ },
+ {name: "onyx.TooltipDecorator", description: "Combines a conrol (typically a button) and a tooltip describing it",
+ inline: {kind: "onyx.Tooltip"},
+ config: {kind: "onyx.TooltipDecorator", components: [
+ {kind: "onyx.Button", content: "Hover for tooltip"},
+ {kind: "onyx.Tooltip", content: "I'm a tooltip for a button."}
+ ]}
+ }
+ ]}
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourcepackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+enyo.depends(
+ "Icon.js",
+ "Button.js",
+ "IconButton.js",
+ "Checkbox.js",
+ "Drawer.js",
+ "Grabber.js",
+ "Groupbox.js",
+ "Input.js",
+ "Popup.js",
+ "TextArea.js",
+ "RichText.js",
+ "InputDecorator.js",
+ "Tooltip.js",
+ "TooltipDecorator.js",
+ "MenuDecorator.js",
+ "Menu.js",
+ "MenuItem.js",
+ "PickerDecorator.js",
+ "PickerButton.js",
+ "Picker.js",
+ "FlyweightPicker.js",
+ "DatePicker.js",
+ "TimePicker.js",
+ "RadioButton.js",
+ "RadioGroup.js",
+ "ToggleButton.js",
+ "ToggleIconButton.js",
+ "Toolbar.js",
+ "Tooltip.js",
+ "TooltipDecorator.js",
+ "ProgressBar.js",
+ "ProgressButton.js",
+ "Scrim.js",
+ "Slider.js",
+ "RangeSlider.js",
+ "Item.js",
+ "Spinner.js",
+ "MoreToolbar.js",
+ "IntegerPicker.js",
+ "ContextualPopup.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunklibonyxsourcewippackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/lib/onyx/source/wip-package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/lib/onyx/source/wip-package.js (rev 0)
+++ 2013/sayaksarkar/trunk/lib/onyx/source/wip-package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+enyo.depends(
+ "TabPanels.js"
+);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunkmanifestwebapp"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/manifest.webapp (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/manifest.webapp (rev 0)
+++ 2013/sayaksarkar/trunk/manifest.webapp 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+{
+ "version": "0.01",
+ "name": "WordPress",
+ "launch_path": "/index.html",
+ "description": "WordPress for Firefox OS.",
+ "icons": {
+ "30": "/images/icon30.png",
+ "48": "/images/icon48.png",
+ "60": "/images/icon60.png",
+ "64": "/images/icon64.png",
+ "128": "/images/icon128.png"
+ },
+ "developer": {
+ "name": "Sayak Sarkar",
+ "url": "http://sayak.in"
+ },
+ "default_locale": "en",
+ "permissions": {
+ }
+}
</ins></span></pre></div>
<a id="2013sayaksarkartrunkpackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+/*
+ == DO NOT EDIT THIS FILE! ==
+ This is necessary to keep paths correct for the minification process
+*/
+enyo.depends("source");
</ins></span></pre></div>
<a id="2013sayaksarkartrunksourceappcss"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/source/app.css (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/source/app.css (rev 0)
+++ 2013/sayaksarkar/trunk/source/app.css 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,67 @@
</span><ins>+/*
+ Put anything you reference with "url()" in ../assets/
+ This way, you can minify your application, and just remove the "source" folder for production
+*/
+.nice-padding {
+ padding: 15px;
+}
+
+/* Posts */
+.listItemContainer {
+ height:50px;
+ color:#777;
+ font-weight: bold;
+ background: #fff;
+ font-size:1.2em;
+ padding:10px;
+ border-bottom:1px solid gray;
+}
+
+/*Compose*/
+.toolbarButton {
+ height: 32px;
+ margin: 6px;
+ width: 32px;
+ text-align: center;
+}
+
+.buttonIcon {
+ margin-left: 7px;
+}
+
+#strongButton {
+ font-weight: bold;
+}
+
+#emButton {
+ font-style: italic;
+}
+
+#uButton {
+ text-decoration: underline;
+}
+
+#strikethroughButton {
+ text-decoration: line-through;
+ text-align: center;
+}
+
+#refresh {
+ margin-left: -1px;
+ margin-top: -4.5px;
+}
+
+#newContent {
+ margin-left: -1px;
+ margin-top: -5px;
+}
+
+#drawer {
+ margin-left: 10.5px;
+ margin-top: -2px;
+}
+
+#back {
+ margin-left: -5px;
+ margin-top: -5px;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="2013sayaksarkartrunksourcecomposejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/source/compose.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/source/compose.js (rev 0)
+++ 2013/sayaksarkar/trunk/source/compose.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+enyo.kind({
+ name: "wp.Compose",
+ kind: "FittableRows",
+ fit: true,
+ classes: "enyo-fit",
+ components:[
+
+ //Header Toolbar Definition
+ {kind: "onyx.Toolbar", layoutKind:"FittableColumnsLayout", components: [
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "backTap", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "back", src: "images/toolbar/back.png"},
+ ]},
+ {content: "New Post", fit: true},
+ {kind: "onyx.Button", content: "Preview", ontap: "previewTap"},
+ {kind: "onyx.Button", content: "Save Draft", ontap: "saveDraftTap"},
+ {kind: "onyx.Button", content: "Publish", ontap: "publishTap"},
+ ]},
+
+ {name: "main", classes: "nice-padding", layoutKind:"FittableRowsLayout", fit: true, components: [
+
+ //Title Input box Definition
+ {
+ layoutKind:"FittableColumnsLayout", components: [
+ {kind: "onyx.InputDecorator", fit: true, components: [
+ {kind: "onyx.Input", name: "title", placeholder: "Title"}
+ ]}
+ ]
+ },
+
+ //Post Text Area Definition
+ {kind: "onyx.Groupbox", style: "margin-top: 15px; ", layoutKind:"FittableRowsLayout", fit: true, components: [
+
+ //WYSIWYG Toolbar Definition
+ {kind: "onyx.GroupboxHeader", components: [
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "boldTap", components: [
+ {kind: "onyx.Icon", id: "strongButton", content: "B"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "italicTap", components: [
+ {kind: "onyx.Icon", id: "emButton", content: "I"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "boldTap", components: [
+ {kind: "onyx.Icon", id: "strikethroughButton", content: "ABC"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "underlineTap", components: [
+ {kind: "onyx.Icon", id: "uButton", content: "U"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "ulTap", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "ulButton", src: "images/compose/icon_ul.png"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "olTap", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "olButton", src: "images/compose/icon_ol.png"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "blockquoteTap", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "blockquoteButton", src: "images/compose/icon_bquote.png"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "linkTap", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "linkButton", src: "images/compose/icon_link.png"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "moreTap", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "moreButton", src: "images/compose/icon_more.png"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "leftTap", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "leftButton", src: "images/compose/icon_left.png"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "centerTap", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "centerButton", src: "images/compose/icon_center.png"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "rightTap", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "rightButton", src: "images/compose/icon_right.png"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "imageTap", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "imageButton", src: "images/compose/icon_camera.png"}
+ ]},
+ ]},
+
+ //Main Scroller Definition
+ {kind: "enyo.Scroller", fit: true, horizontal: "hidden", layoutKind:"FittableRowsLayout", touch: true, thumb: true, components: [
+
+ //Text Input Area Definition
+ {kind: "onyx.InputDecorator", layoutKind:"FittableRowsLayout", fit: true, style: "width: 100%; height: 100%;", components: [
+ {kind: "onyx.RichText", name: "contentField", fit: true, style: "width: 100%;"}
+ ]}
+ ]},
+
+ //Settings Toolbar Definition
+ {kind: "onyx.Toolbar", layoutKind:"FittableColumnsLayout", components: [
+ {kind: "onyx.Button", content: "Setings", fit: true, style: "margin-bottom:0;", ontap: "settingsTap"}
+ ]}
+ ]}
+ ]}
+ ],
+ publishTap: function (inSender, inEvent) {
+ this.payLoad = {};
+ this.payLoad.title = this.$.title.getValue();
+ this.payLoad.contentField = this.$.contentField.getValue();
+ console.log(this.payLoad);
+ return this.payLoad;
+ },
+ previewTap: function (inSender, inEvent) {
+ this.payLoad = {};
+ this.payLoad.title = this.$.title.getValue();
+ this.payLoad.contentField = this.$.contentField.getValue();
+ console.log(this.payLoad);
+ return this.payLoad;
+ },
+ saveDraftTap: function (inSender, inEvent) {
+ this.payLoad = {};
+ this.payLoad.title = this.$.title.getValue();
+ this.payLoad.contentField = this.$.contentField.getValue();
+ console.log(this.payLoad);
+ return this.payLoad;
+ },
+ backTap: function(inSender, inEvent) {
+ new wp.Posts().renderInto(document.body);
+ },
+ settingsTap: function(inSender, inEvent) {
+ alert("The Settings Panel is still under Construction.");
+ }
+});
</ins></span></pre></div>
<a id="2013sayaksarkartrunksourcepackagejs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/source/package.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/source/package.js (rev 0)
+++ 2013/sayaksarkar/trunk/source/package.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+enyo.depends(
+ "$lib/layout",
+ "$lib/onyx", // To theme Onyx using Theme.less, change this line to $lib/onyx/source,
+ //"Theme.less", // uncomment this line, and follow the steps described in Theme.less
+ "app.css",
+ "compose.js",
+ "posts.js"
+);
</ins></span></pre></div>
<a id="2013sayaksarkartrunksourcepostsjs"></a>
<div class="addfile"><h4>Added: 2013/sayaksarkar/trunk/source/posts.js (0 => 2146)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/sayaksarkar/trunk/source/posts.js (rev 0)
+++ 2013/sayaksarkar/trunk/source/posts.js 2013-07-23 16:49:28 UTC (rev 2146)
</span><span class="lines">@@ -0,0 +1,72 @@
</span><ins>+enyo.kind({
+ name: "wp.Posts",
+ kind: "FittableRows",
+ fit: true,classes: "enyo-fit",
+ components:[
+
+ //Header Toolbar Definition
+ {kind: "onyx.Toolbar", layoutKind:"FittableColumnsLayout", components: [
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "drawerTap", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "drawer", src: "images/toolbar/drawer.png"},
+ ]},
+ {content: "Posts", fit: true},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "refresh", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "refresh", src: "images/toolbar/refresh.png"}
+ ]},
+ {kind: "onyx.Button", classes: "toolbarButton", ontap: "newPostTap", components: [
+ {kind: "onyx.Icon", classes: "buttonIcon", id: "newContent", src: "images/toolbar/new.png"}
+ ]}
+ ]},
+
+ //Posts List Definition
+ {
+ name: "postList",
+ kind: "List",
+ fit: true,
+ count: 0,
+ onSetupItem: "setupItem",
+ components: [
+ {
+ name: "listItem",
+ classes: "listItemContainer",
+ ontap: "listItemTap",
+ components: [
+ {
+ name: "postTitle",
+ content: "Set Title..."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ datasource: [
+ {name: "Installing Sublime Text 2 on Fedora 19 – Schrodinger’s Cat", gist: "Here’s another three step guide to installing Sublime Text 2 on Fedora 19 – Schrodinger’s Cat:- Download the installation script from the following gist. https://gist.github.com/sayak-sarkar/5810101 Extract it to your home directory [or anywhere you like]. $tar -xvf gist5810101-3b0e9bb3ef5128760df9e3e06877fa4f7e5689ec.tar.gz Open your terminal (preferably as super user), navigate to your home directory and execute the shell script."},
+ {name: "Installing VLC player on Fedora 19 – Schrodinger’s Cat", gist: "Here’s a simple three step guide to installing VLC media player on Fedora 19 [Schrodinger's Cat]:- Login as Super User: $su Setup rpmfusion: #rpm -ivh http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm Install vlc using the default yum package manager: #yum install vlc mozilla-vlc Voila! You now have VLC media player installed on you computer! Filed under: Fedora, How-to Guides, Technology,"},
+ {name: "Porting WordPress for WebOS to Firefox OS", gist: "Introduction to WordPress for WebOS WordPress for WebOS was a web app which used the WebOS platform’s innovative “Cards” feature, which allowed users to quickly switch between managing, editing, and browsing content. WordPress for WebOS was built around Sliding Panels that enables users to easily switch between creating, editing and managing content. The app allowed "},
+ {name: "Programming on Mobile Devices", gist: "This is a thought that’s been rather bugging me for sometime now: Is writing code (programming) via mobile devices really not a very feasible idea? In the current scenario, almost all conventional programming is done on desktop computers (PCs, laptops and the likes), wherein we have a standard keyboard which is used to write down "},
+ {name: "The Greek Experience – Remo Training Days", gist: "Last week Mozilla brought together 40 Mozilla Reps from all over the world at Athens for week-long training exercise called Reps Training Days. The idea was to gather the most pro-active Mozillians under the ReMo programme in a single place and train them about leading the Webmaker initiative in their respective communities. The training event "},
+ {name: "Running Friendlycode – A local instance of Thimble", gist: "Here is a breakdown of how to run Friendlycode in 3 (maybe not-so-simple) steps. Prerequisite: A static file server such as Apache. Steps:- Download Friendlycode from here. Extract the contents of the friendlycode-gh-pages package into a directory named friendlycode within your file server’s document root. For example, in Apache you might want to put the "},
+ {name: "Installing Steam for Linux Beta | Counter Strike for Fedora 17/18", gist: "Here’s the link to a really interesting article by Russel Bryant that I found on the web. Especially helpful for all my geeky gamer friends who keep on complaining about how they are not able to play Counter Strike or Team Fortress 2 on their Linux based systems. Enjoy! If however you are a counter"},
+ {name: "Debugging NO KEY warning during “yum install vlc”", gist: "This is a problem that I encountered today while tryiing to install VLC media player on my brand new Fedora 18 installation. Right after the dependency resolutions are complete, yum returns the following warning:- Transaction Summary =============================================== Install 1 Package (+45 Dependent packages) Total size: 37 M Installed size: 118 M Is this ok [y/N]:"},
+ {name: "LAMP Setup for Fedora 18", gist: "Easy steps to setup Fedora 18 as a LAMP server containing Apache, PHP, Perl, Python, Ruby and MySQL. P.S.: This requires root access to the shell. Step 1: Open terminal as root user and enter the following: #yum install -y httpd php php-mysql php-gd php-imap php-ldap php-odbc php-pear php-xml php-xmlrpc php-magickwand php-mbstring php-mcrypt php-mssql php-shout"},
+ {name: "Adobe Flex Builder 3 Download", gist: "Reblogged from Chris Tierney: I had to track down a download location for Adobe's Flex 3 install today. It was a little hard to find so I thought I'd share this link for a Windows install: http://download.macromedia.com/pub/flex/flex_builder/FB3_win.exe Why it's at a macromedia.com address I have no clue, but hope this helps someone out. This defaults"}
+ ],
+ create: function () {
+ this.inherited(arguments);
+ this.$.postList.setCount(this.datasource.length);
+ },
+ setupItem: function (inSender, inEvent) {
+ this.childName = this.datasource[inEvent.index].name;
+ this.$.postTitle.setContent(this.childName);
+ },
+ listItemTap:function(inSender, inEvent) {
+ alert(this.datasource[inEvent.index].gist);
+ },
+ newPostTap: function(inSender, inEvent) {
+ new wp.Compose().renderInto(document.body);
+ },
+ stub: function(inSender, inEvent) {
+ this.$.main.addContent("<br/>");
+ }
+});
</ins></span></pre>
</div>
</div>
</body>
</html>