Permalink
Browse files

single master to many works operational, refactored redis wrappers an…

…d added license
  • Loading branch information...
1 parent c7bbe5d commit 4edc092f9048de4ca90ff9a3eec7eb44c77436dd Roger Castillo committed Dec 29, 2011
Showing with 1,342 additions and 220 deletions.
  1. +1,129 −0 epl-v10.html
  2. +39 −85 lib/channels.js
  3. +34 −29 lib/qrx.js
  4. +100 −95 lib/work.js
  5. +22 −11 test/qrx-test.js
  6. +18 −0 test/work-test.js
View
1,129 epl-v10.html
@@ -0,0 +1,1129 @@
+
+
+
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset='utf-8'>
+ <meta http-equiv="X-UA-Compatible" content="chrome=1">
+ <title>epl-v10.html at master from clojure/clojurescript - GitHub</title>
+ <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub" />
+ <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub" />
+
+
+
+
+ <meta content="authenticity_token" name="csrf-param" />
+<meta content="Tk0Lhdu64itsLomnekch1PcWZSW4dtvJRHlWY0uHKiE=" name="csrf-token" />
+
+ <link href="https://a248.e.akamai.net/assets.github.com/stylesheets/bundles/github-e674c5ccbbd624fea35cfac8c5368c560d81b210.css" media="screen" rel="stylesheet" type="text/css" />
+
+
+ <script src="https://a248.e.akamai.net/assets.github.com/javascripts/bundles/jquery-d4fdb3ac9b569d829e38630363e4f9a336e4fca5.js" type="text/javascript"></script>
+ <script src="https://a248.e.akamai.net/assets.github.com/javascripts/bundles/github-18159b5779feb810427fa5a575cb64d483b43a31.js" type="text/javascript"></script>
+
+
+ <link rel='permalink' href='/clojure/clojurescript/blob/13e73bacc3cee2bbdcdce908ad3f48b4a5565d42/epl-v10.html'>
+
+
+ <meta name="description" content="clojurescript - Clojure to JS compiler" />
+ <link href="https://github.com/clojure/clojurescript/commits/master.atom" rel="alternate" title="Recent Commits to clojurescript:master" type="application/atom+xml" />
+
+ </head>
+
+
+ <body class="logged_in page-blob linux env-production ">
+
+
+
+
+ <div id="main">
+ <div id="header" class="true">
+ <a class="logo" href="/">
+ <img alt="github" class="default svg" height="45" src="https://a248.e.akamai.net/assets.github.com/images/modules/header/logov6.svg?1315858591" />
+ <img alt="github" class="default png" height="45" src="https://a248.e.akamai.net/assets.github.com/images/modules/header/logov6.png?1315858591" />
+ <!--[if (gt IE 8)|!(IE)]><!-->
+ <img alt="github" class="hover svg" height="45" src="https://a248.e.akamai.net/assets.github.com/images/modules/header/logov6-hover.svg?1315858591" />
+ <img alt="github" class="hover png" height="45" src="https://a248.e.akamai.net/assets.github.com/images/modules/header/logov6-hover.png?1315858591" />
+ <!--<![endif]-->
+ </a>
+
+
+
+
+
+ <div class="userbox">
+ <div class="avatarname">
+ <a href="https://github.com/rcastillo"><img height="20" src="https://secure.gravatar.com/avatar/a8b891d74286c44718e3b7c89200e53f?s=140&amp;d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png" width="20" /></a>
+ <a href="https://github.com/rcastillo" class="name">rcastillo</a>
+ </div>
+ <ul class="usernav">
+ <li><a href="https://github.com/">Dashboard</a></li>
+ <li>
+ <a href="https://github.com/inbox/notifications">Inbox</a>
+ <a href="https://github.com/inbox/notifications" class="unread_count new js-inbox-count">217</a>
+ </li>
+ <li><a href="https://github.com/account">Account Settings</a></li>
+ <li><a href="/logout">Log Out</a></li>
+ </ul>
+ </div><!-- /.userbox -->
+
+
+
+ <div class="topsearch">
+<form action="/search" id="top_search_form" method="get"> <a href="/search" class="advanced-search tooltipped downwards" title="Advanced Search">Advanced Search</a>
+ <div class="search placeholder-field js-placeholder-field">
+ <label class="placeholder" for="global-search-field">Search…</label>
+ <input type="text" class="search my_repos_autocompleter" id="global-search-field" name="q" results="5" /> <input type="submit" value="Search" class="button" />
+ </div>
+ <input type="hidden" name="type" value="Everything" />
+ <input type="hidden" name="repo" value="" />
+ <input type="hidden" name="langOverride" value="" />
+ <input type="hidden" name="start_value" value="1" />
+</form> <ul class="nav">
+ <li class="explore"><a href="https://github.com/explore">Explore GitHub</a></li>
+ <li><a href="https://gist.github.com">Gist</a></li>
+ <li><a href="/blog">Blog</a></li>
+ <li><a href="http://help.github.com">Help</a></li>
+ </ul>
+</div>
+
+ </div>
+
+
+ <div class="site">
+ <div class="pagehead repohead vis-public fork instapaper_ignore readability-menu">
+
+
+ <div class="title-actions-bar">
+ <h1>
+ <a href="/clojure">clojure</a> /
+ <strong><a href="/clojure/clojurescript" class="js-current-repository">clojurescript</a></strong>
+ <span class="fork-flag">
+ <span class="text">forked from <a href="/relevance/clojurescript">relevance/clojurescript</a></span>
+ </span>
+ </h1>
+
+
+
+
+ <ul class="pagehead-actions">
+
+
+ <li class="js-toggler-container watch-button-container ">
+ <a href="/clojure/clojurescript/toggle_watch" class="minibutton btn-watch watch-button js-toggler-target" data-method="post" data-remote="true" rel="nofollow"><span><span class="icon"></span>Watch</span></a>
+ <a href="/clojure/clojurescript/toggle_watch" class="minibutton btn-watch unwatch-button js-toggler-target" data-method="post" data-remote="true" rel="nofollow"><span><span class="icon"></span>Unwatch</span></a>
+ </li>
+
+ <li><a href="/clojure/clojurescript/fork_select" class="minibutton btn-fork " rel="facebox nofollow"><span><span class="icon"></span>Fork</span></a></li>
+
+
+
+ <li class="repostats">
+ <ul class="repo-stats">
+ <li class="watchers ">
+ <a href="/clojure/clojurescript/watchers" title="Watchers" class="tooltipped downwards">
+ 914
+ </a>
+ </li>
+ <li class="forks">
+ <a href="/clojure/clojurescript/network" title="Forks" class="tooltipped downwards">
+ 86
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+
+ </div>
+
+
+
+ <ul class="tabs">
+ <li><a href="/clojure/clojurescript" class="selected" highlight="repo_sourcerepo_downloadsrepo_commitsrepo_tagsrepo_branches">Code</a></li>
+ <li><a href="/clojure/clojurescript/network" highlight="repo_networkrepo_fork_queue">Network</a>
+ <li><a href="/clojure/clojurescript/pulls" highlight="repo_pulls">Pull Requests <span class='counter'>0</span></a></li>
+
+
+ <li><a href="/clojure/clojurescript/wiki" highlight="repo_wiki">Wiki <span class='counter'>19</span></a></li>
+
+ <li><a href="/clojure/clojurescript/graphs" highlight="repo_graphsrepo_contributors">Stats &amp; Graphs</a></li>
+
+ </ul>
+
+
+<div class="frame frame-center tree-finder" style="display:none"
+ data-tree-list-url="/clojure/clojurescript/tree-list/13e73bacc3cee2bbdcdce908ad3f48b4a5565d42"
+ data-blob-url-prefix="/clojure/clojurescript/blob/13e73bacc3cee2bbdcdce908ad3f48b4a5565d42"
+ >
+
+ <div class="breadcrumb">
+ <b><a href="/clojure/clojurescript">clojurescript</a></b> /
+ <input class="tree-finder-input js-navigation-enable" type="text" name="query" autocomplete="off" spellcheck="false">
+ </div>
+
+ <div class="octotip">
+ <p>
+ <a href="/clojure/clojurescript/dismiss-tree-finder-help" class="dismiss js-dismiss-tree-list-help" title="Hide this notice forever" rel="nofollow">Dismiss</a>
+ <strong>Octotip:</strong> You've activated the <em>file finder</em>
+ by pressing <span class="kbd">t</span> Start typing to filter the
+ file list. Use <span class="kbd badmono">↑</span> and
+ <span class="kbd badmono">↓</span> to navigate,
+ <span class="kbd">enter</span> to view files.
+ </p>
+ </div>
+
+ <table class="tree-browser" cellpadding="0" cellspacing="0">
+ <tr class="js-header"><th>&nbsp;</th><th>name</th></tr>
+ <tr class="js-no-results no-results" style="display: none">
+ <th colspan="2">No matching files</th>
+ </tr>
+ <tbody class="js-results-list js-navigation-container">
+ </tbody>
+ </table>
+</div>
+
+<div id="jump-to-line" style="display:none">
+ <h2>Jump to Line</h2>
+ <form>
+ <input class="textfield" type="text">
+ <div class="full-button">
+ <button type="submit" class="classy">
+ <span>Go</span>
+ </button>
+ </div>
+ </form>
+</div>
+
+
+<div class="subnav-bar">
+
+ <ul class="actions">
+
+ <li class="switcher">
+
+ <div class="context-menu-container js-menu-container">
+ <span class="text">Current branch:</span>
+ <a href="#"
+ class="minibutton bigger switcher context-menu-button js-menu-target js-commitish-button btn-branch repo-tree"
+ data-master-branch="master"
+ data-ref="master">
+ <span><span class="icon"></span>master</span>
+ </a>
+
+ <div class="context-pane commitish-context js-menu-content">
+ <a href="javascript:;" class="close js-menu-close"></a>
+ <div class="title">Switch Branches/Tags</div>
+ <div class="body pane-selector commitish-selector js-filterable-commitishes">
+ <div class="filterbar">
+ <div class="placeholder-field js-placeholder-field">
+ <label class="placeholder" for="context-commitish-filter-field" data-placeholder-mode="sticky">Filter branches/tags</label>
+ <input type="text" id="context-commitish-filter-field" class="commitish-filter" />
+ </div>
+
+ <ul class="tabs">
+ <li><a href="#" data-filter="branches" class="selected">Branches</a></li>
+ <li><a href="#" data-filter="tags">Tags</a></li>
+ </ul>
+ </div>
+
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/33-type-fn/epl-v10.html" data-name="33-type-fn">33-type-fn</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/37-support-for-js-literals/epl-v10.html" data-name="37-support-for-js-literals">37-support-for-js-literals</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/4-math-op-macros/epl-v10.html" data-name="4-math-op-macros">4-math-op-macros</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/52-cli/epl-v10.html" data-name="52-cli">52-cli</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/53-defrecord/epl-v10.html" data-name="53-defrecord">53-defrecord</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/80-inline-truth/epl-v10.html" data-name="80-inline-truth">80-inline-truth</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/83-deftype-methods/epl-v10.html" data-name="83-deftype-methods">83-deftype-methods</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/84-str-symbol/epl-v10.html" data-name="84-str-symbol">84-str-symbol</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/85-read-keyword/epl-v10.html" data-name="85-read-keyword">85-read-keyword</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/96-ifn/epl-v10.html" data-name="96-ifn">96-ifn</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/98-fix-instance/epl-v10.html" data-name="98-fix-instance">98-fix-instance</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/atom-watches/epl-v10.html" data-name="atom-watches">atom-watches</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/ext-js-sample/epl-v10.html" data-name="ext-js-sample">ext-js-sample</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/master/epl-v10.html" data-name="master">master</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/multi-methods/epl-v10.html" data-name="multi-methods">multi-methods</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/persistent-queue/epl-v10.html" data-name="persistent-queue">persistent-queue</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/prop-lookup/epl-v10.html" data-name="prop-lookup">prop-lookup</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/reader-fixes/epl-v10.html" data-name="reader-fixes">reader-fixes</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/this/epl-v10.html" data-name="this">this</a>
+ </h4>
+ </div>
+ <div class="commitish-item branch-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/use-only/epl-v10.html" data-name="use-only">use-only</a>
+ </h4>
+ </div>
+
+ <div class="commitish-item tag-commitish selector-item">
+ <h4>
+ <a href="/clojure/clojurescript/blob/v0.0/epl-v10.html" data-name="v0.0">v0.0</a>
+ </h4>
+ </div>
+
+ <div class="no-results" style="display:none">Nothing to show</div>
+ </div>
+ </div><!-- /.commitish-context-context -->
+ </div>
+
+ </li>
+ </ul>
+
+ <ul class="subnav">
+ <li><a href="/clojure/clojurescript" class="selected" highlight="repo_source">Files</a></li>
+ <li><a href="/clojure/clojurescript/commits/master" highlight="repo_commits">Commits</a></li>
+ <li><a href="/clojure/clojurescript/branches" class="" highlight="repo_branches">Branches <span class="counter">20</span></a></li>
+ <li><a href="/clojure/clojurescript/tags" class="" highlight="repo_tags">Tags <span class="counter">1</span></a></li>
+ <li><a href="/clojure/clojurescript/downloads" class="" highlight="repo_downloads">Downloads <span class="counter">1</span></a></li>
+ </ul>
+
+</div>
+
+
+
+
+
+
+
+
+ </div><!-- /.pagehead -->
+
+
+
+
+
+
+
+ <p class="last-commit">Latest commit to the <strong>master</strong> branch</p>
+
+<div class="commit commit-tease js-details-container">
+ <p class="commit-title ">
+ <a href="/clojure/clojurescript/commit/13e73bacc3cee2bbdcdce908ad3f48b4a5565d42" class="message">Add set-properties, set-value and click-element to clojure.browser.dom.</a>
+
+ </p>
+ <div class="commit-meta">
+ <a href="/clojure/clojurescript/commit/13e73bacc3cee2bbdcdce908ad3f48b4a5565d42" class="sha-block">commit <span class="sha">13e73bacc3</span></a>
+
+ <div class="authorship">
+ <img class="gravatar" height="20" src="https://secure.gravatar.com/avatar/0fe5a692122f652c5d69e882ba148071?s=140&amp;d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png" width="20" />
+ <span class="author-name">Brenton Ashworth</span>
+ authored <time class="js-relative-date" datetime="2011-12-04T04:28:12-08:00" title="2011-12-04 04:28:12">December 04, 2011</time>
+
+ </div>
+ </div>
+</div>
+
+
+ <div id="slider">
+
+ <div class="breadcrumb" data-path="epl-v10.html/">
+ <b><a href="/clojure/clojurescript/tree/1e063940ffa6f350dc1691a78da6f12d894fa4a3" class="js-rewrite-sha">clojurescript</a></b> / epl-v10.html <span style="display:none" id="clippy_1675" class="clippy-text">epl-v10.html</span>
+
+ <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
+ width="110"
+ height="14"
+ class="clippy"
+ id="clippy" >
+ <param name="movie" value="https://a248.e.akamai.net/assets.github.com/flash/clippy.swf?1261951368?v5"/>
+ <param name="allowScriptAccess" value="always" />
+ <param name="quality" value="high" />
+ <param name="scale" value="noscale" />
+ <param NAME="FlashVars" value="id=clippy_1675&amp;copied=copied!&amp;copyto=copy to clipboard">
+ <param name="bgcolor" value="#FFFFFF">
+ <param name="wmode" value="opaque">
+ <embed src="https://a248.e.akamai.net/assets.github.com/flash/clippy.swf?1261951368?v5"
+ width="110"
+ height="14"
+ name="clippy"
+ quality="high"
+ allowScriptAccess="always"
+ type="application/x-shockwave-flash"
+ pluginspage="http://www.macromedia.com/go/getflashplayer"
+ FlashVars="id=clippy_1675&amp;copied=copied!&amp;copyto=copy to clipboard"
+ bgcolor="#FFFFFF"
+ wmode="opaque"
+ />
+ </object>
+
+
+ </div>
+
+ <div class="frames">
+ <div class="frame frame-center" data-path="epl-v10.html/" data-permalink-url="/clojure/clojurescript/blob/1e063940ffa6f350dc1691a78da6f12d894fa4a3/epl-v10.html" data-title="epl-v10.html at 1e063940ffa6f350dc1691a78da6f12d894fa4a3 from clojure/clojurescript - GitHub" data-type="blob">
+ <ul class="big-actions">
+ <li><a class="file-edit-link minibutton js-rewrite-sha" href="/clojure/clojurescript/edit/1e063940ffa6f350dc1691a78da6f12d894fa4a3/epl-v10.html" data-method="post" rel="nofollow"><span>Edit this file</span></a></li>
+ </ul>
+
+ <div id="files">
+ <div class="file">
+ <div class="meta">
+ <div class="info">
+ <span class="icon"><img alt="Txt" height="16" src="https://a248.e.akamai.net/assets.github.com/images/icons/txt.png?1252203928" width="16" /></span>
+ <span class="mode" title="File Mode">100644</span>
+ <span>262 lines (216 sloc)</span>
+ <span>12.917 kb</span>
+ </div>
+ <ul class="actions">
+ <li><a href="/clojure/clojurescript/raw/1e063940ffa6f350dc1691a78da6f12d894fa4a3/epl-v10.html" id="raw-url">raw</a></li>
+ <li><a href="/clojure/clojurescript/blame/1e063940ffa6f350dc1691a78da6f12d894fa4a3/epl-v10.html">blame</a></li>
+ <li><a href="/clojure/clojurescript/commits/1e063940ffa6f350dc1691a78da6f12d894fa4a3/epl-v10.html" rel="nofollow">history</a></li>
+ </ul>
+ </div>
+ <div class="data type-html">
+ <table cellpadding="0" cellspacing="0" class="lines">
+ <tr>
+ <td>
+ <pre class="line_numbers"><span id="L1" rel="#L1">1</span>
+<span id="L2" rel="#L2">2</span>
+<span id="L3" rel="#L3">3</span>
+<span id="L4" rel="#L4">4</span>
+<span id="L5" rel="#L5">5</span>
+<span id="L6" rel="#L6">6</span>
+<span id="L7" rel="#L7">7</span>
+<span id="L8" rel="#L8">8</span>
+<span id="L9" rel="#L9">9</span>
+<span id="L10" rel="#L10">10</span>
+<span id="L11" rel="#L11">11</span>
+<span id="L12" rel="#L12">12</span>
+<span id="L13" rel="#L13">13</span>
+<span id="L14" rel="#L14">14</span>
+<span id="L15" rel="#L15">15</span>
+<span id="L16" rel="#L16">16</span>
+<span id="L17" rel="#L17">17</span>
+<span id="L18" rel="#L18">18</span>
+<span id="L19" rel="#L19">19</span>
+<span id="L20" rel="#L20">20</span>
+<span id="L21" rel="#L21">21</span>
+<span id="L22" rel="#L22">22</span>
+<span id="L23" rel="#L23">23</span>
+<span id="L24" rel="#L24">24</span>
+<span id="L25" rel="#L25">25</span>
+<span id="L26" rel="#L26">26</span>
+<span id="L27" rel="#L27">27</span>
+<span id="L28" rel="#L28">28</span>
+<span id="L29" rel="#L29">29</span>
+<span id="L30" rel="#L30">30</span>
+<span id="L31" rel="#L31">31</span>
+<span id="L32" rel="#L32">32</span>
+<span id="L33" rel="#L33">33</span>
+<span id="L34" rel="#L34">34</span>
+<span id="L35" rel="#L35">35</span>
+<span id="L36" rel="#L36">36</span>
+<span id="L37" rel="#L37">37</span>
+<span id="L38" rel="#L38">38</span>
+<span id="L39" rel="#L39">39</span>
+<span id="L40" rel="#L40">40</span>
+<span id="L41" rel="#L41">41</span>
+<span id="L42" rel="#L42">42</span>
+<span id="L43" rel="#L43">43</span>
+<span id="L44" rel="#L44">44</span>
+<span id="L45" rel="#L45">45</span>
+<span id="L46" rel="#L46">46</span>
+<span id="L47" rel="#L47">47</span>
+<span id="L48" rel="#L48">48</span>
+<span id="L49" rel="#L49">49</span>
+<span id="L50" rel="#L50">50</span>
+<span id="L51" rel="#L51">51</span>
+<span id="L52" rel="#L52">52</span>
+<span id="L53" rel="#L53">53</span>
+<span id="L54" rel="#L54">54</span>
+<span id="L55" rel="#L55">55</span>
+<span id="L56" rel="#L56">56</span>
+<span id="L57" rel="#L57">57</span>
+<span id="L58" rel="#L58">58</span>
+<span id="L59" rel="#L59">59</span>
+<span id="L60" rel="#L60">60</span>
+<span id="L61" rel="#L61">61</span>
+<span id="L62" rel="#L62">62</span>
+<span id="L63" rel="#L63">63</span>
+<span id="L64" rel="#L64">64</span>
+<span id="L65" rel="#L65">65</span>
+<span id="L66" rel="#L66">66</span>
+<span id="L67" rel="#L67">67</span>
+<span id="L68" rel="#L68">68</span>
+<span id="L69" rel="#L69">69</span>
+<span id="L70" rel="#L70">70</span>
+<span id="L71" rel="#L71">71</span>
+<span id="L72" rel="#L72">72</span>
+<span id="L73" rel="#L73">73</span>
+<span id="L74" rel="#L74">74</span>
+<span id="L75" rel="#L75">75</span>
+<span id="L76" rel="#L76">76</span>
+<span id="L77" rel="#L77">77</span>
+<span id="L78" rel="#L78">78</span>
+<span id="L79" rel="#L79">79</span>
+<span id="L80" rel="#L80">80</span>
+<span id="L81" rel="#L81">81</span>
+<span id="L82" rel="#L82">82</span>
+<span id="L83" rel="#L83">83</span>
+<span id="L84" rel="#L84">84</span>
+<span id="L85" rel="#L85">85</span>
+<span id="L86" rel="#L86">86</span>
+<span id="L87" rel="#L87">87</span>
+<span id="L88" rel="#L88">88</span>
+<span id="L89" rel="#L89">89</span>
+<span id="L90" rel="#L90">90</span>
+<span id="L91" rel="#L91">91</span>
+<span id="L92" rel="#L92">92</span>
+<span id="L93" rel="#L93">93</span>
+<span id="L94" rel="#L94">94</span>
+<span id="L95" rel="#L95">95</span>
+<span id="L96" rel="#L96">96</span>
+<span id="L97" rel="#L97">97</span>
+<span id="L98" rel="#L98">98</span>
+<span id="L99" rel="#L99">99</span>
+<span id="L100" rel="#L100">100</span>
+<span id="L101" rel="#L101">101</span>
+<span id="L102" rel="#L102">102</span>
+<span id="L103" rel="#L103">103</span>
+<span id="L104" rel="#L104">104</span>
+<span id="L105" rel="#L105">105</span>
+<span id="L106" rel="#L106">106</span>
+<span id="L107" rel="#L107">107</span>
+<span id="L108" rel="#L108">108</span>
+<span id="L109" rel="#L109">109</span>
+<span id="L110" rel="#L110">110</span>
+<span id="L111" rel="#L111">111</span>
+<span id="L112" rel="#L112">112</span>
+<span id="L113" rel="#L113">113</span>
+<span id="L114" rel="#L114">114</span>
+<span id="L115" rel="#L115">115</span>
+<span id="L116" rel="#L116">116</span>
+<span id="L117" rel="#L117">117</span>
+<span id="L118" rel="#L118">118</span>
+<span id="L119" rel="#L119">119</span>
+<span id="L120" rel="#L120">120</span>
+<span id="L121" rel="#L121">121</span>
+<span id="L122" rel="#L122">122</span>
+<span id="L123" rel="#L123">123</span>
+<span id="L124" rel="#L124">124</span>
+<span id="L125" rel="#L125">125</span>
+<span id="L126" rel="#L126">126</span>
+<span id="L127" rel="#L127">127</span>
+<span id="L128" rel="#L128">128</span>
+<span id="L129" rel="#L129">129</span>
+<span id="L130" rel="#L130">130</span>
+<span id="L131" rel="#L131">131</span>
+<span id="L132" rel="#L132">132</span>
+<span id="L133" rel="#L133">133</span>
+<span id="L134" rel="#L134">134</span>
+<span id="L135" rel="#L135">135</span>
+<span id="L136" rel="#L136">136</span>
+<span id="L137" rel="#L137">137</span>
+<span id="L138" rel="#L138">138</span>
+<span id="L139" rel="#L139">139</span>
+<span id="L140" rel="#L140">140</span>
+<span id="L141" rel="#L141">141</span>
+<span id="L142" rel="#L142">142</span>
+<span id="L143" rel="#L143">143</span>
+<span id="L144" rel="#L144">144</span>
+<span id="L145" rel="#L145">145</span>
+<span id="L146" rel="#L146">146</span>
+<span id="L147" rel="#L147">147</span>
+<span id="L148" rel="#L148">148</span>
+<span id="L149" rel="#L149">149</span>
+<span id="L150" rel="#L150">150</span>
+<span id="L151" rel="#L151">151</span>
+<span id="L152" rel="#L152">152</span>
+<span id="L153" rel="#L153">153</span>
+<span id="L154" rel="#L154">154</span>
+<span id="L155" rel="#L155">155</span>
+<span id="L156" rel="#L156">156</span>
+<span id="L157" rel="#L157">157</span>
+<span id="L158" rel="#L158">158</span>
+<span id="L159" rel="#L159">159</span>
+<span id="L160" rel="#L160">160</span>
+<span id="L161" rel="#L161">161</span>
+<span id="L162" rel="#L162">162</span>
+<span id="L163" rel="#L163">163</span>
+<span id="L164" rel="#L164">164</span>
+<span id="L165" rel="#L165">165</span>
+<span id="L166" rel="#L166">166</span>
+<span id="L167" rel="#L167">167</span>
+<span id="L168" rel="#L168">168</span>
+<span id="L169" rel="#L169">169</span>
+<span id="L170" rel="#L170">170</span>
+<span id="L171" rel="#L171">171</span>
+<span id="L172" rel="#L172">172</span>
+<span id="L173" rel="#L173">173</span>
+<span id="L174" rel="#L174">174</span>
+<span id="L175" rel="#L175">175</span>
+<span id="L176" rel="#L176">176</span>
+<span id="L177" rel="#L177">177</span>
+<span id="L178" rel="#L178">178</span>
+<span id="L179" rel="#L179">179</span>
+<span id="L180" rel="#L180">180</span>
+<span id="L181" rel="#L181">181</span>
+<span id="L182" rel="#L182">182</span>
+<span id="L183" rel="#L183">183</span>
+<span id="L184" rel="#L184">184</span>
+<span id="L185" rel="#L185">185</span>
+<span id="L186" rel="#L186">186</span>
+<span id="L187" rel="#L187">187</span>
+<span id="L188" rel="#L188">188</span>
+<span id="L189" rel="#L189">189</span>
+<span id="L190" rel="#L190">190</span>
+<span id="L191" rel="#L191">191</span>
+<span id="L192" rel="#L192">192</span>
+<span id="L193" rel="#L193">193</span>
+<span id="L194" rel="#L194">194</span>
+<span id="L195" rel="#L195">195</span>
+<span id="L196" rel="#L196">196</span>
+<span id="L197" rel="#L197">197</span>
+<span id="L198" rel="#L198">198</span>
+<span id="L199" rel="#L199">199</span>
+<span id="L200" rel="#L200">200</span>
+<span id="L201" rel="#L201">201</span>
+<span id="L202" rel="#L202">202</span>
+<span id="L203" rel="#L203">203</span>
+<span id="L204" rel="#L204">204</span>
+<span id="L205" rel="#L205">205</span>
+<span id="L206" rel="#L206">206</span>
+<span id="L207" rel="#L207">207</span>
+<span id="L208" rel="#L208">208</span>
+<span id="L209" rel="#L209">209</span>
+<span id="L210" rel="#L210">210</span>
+<span id="L211" rel="#L211">211</span>
+<span id="L212" rel="#L212">212</span>
+<span id="L213" rel="#L213">213</span>
+<span id="L214" rel="#L214">214</span>
+<span id="L215" rel="#L215">215</span>
+<span id="L216" rel="#L216">216</span>
+<span id="L217" rel="#L217">217</span>
+<span id="L218" rel="#L218">218</span>
+<span id="L219" rel="#L219">219</span>
+<span id="L220" rel="#L220">220</span>
+<span id="L221" rel="#L221">221</span>
+<span id="L222" rel="#L222">222</span>
+<span id="L223" rel="#L223">223</span>
+<span id="L224" rel="#L224">224</span>
+<span id="L225" rel="#L225">225</span>
+<span id="L226" rel="#L226">226</span>
+<span id="L227" rel="#L227">227</span>
+<span id="L228" rel="#L228">228</span>
+<span id="L229" rel="#L229">229</span>
+<span id="L230" rel="#L230">230</span>
+<span id="L231" rel="#L231">231</span>
+<span id="L232" rel="#L232">232</span>
+<span id="L233" rel="#L233">233</span>
+<span id="L234" rel="#L234">234</span>
+<span id="L235" rel="#L235">235</span>
+<span id="L236" rel="#L236">236</span>
+<span id="L237" rel="#L237">237</span>
+<span id="L238" rel="#L238">238</span>
+<span id="L239" rel="#L239">239</span>
+<span id="L240" rel="#L240">240</span>
+<span id="L241" rel="#L241">241</span>
+<span id="L242" rel="#L242">242</span>
+<span id="L243" rel="#L243">243</span>
+<span id="L244" rel="#L244">244</span>
+<span id="L245" rel="#L245">245</span>
+<span id="L246" rel="#L246">246</span>
+<span id="L247" rel="#L247">247</span>
+<span id="L248" rel="#L248">248</span>
+<span id="L249" rel="#L249">249</span>
+<span id="L250" rel="#L250">250</span>
+<span id="L251" rel="#L251">251</span>
+<span id="L252" rel="#L252">252</span>
+<span id="L253" rel="#L253">253</span>
+<span id="L254" rel="#L254">254</span>
+<span id="L255" rel="#L255">255</span>
+<span id="L256" rel="#L256">256</span>
+<span id="L257" rel="#L257">257</span>
+<span id="L258" rel="#L258">258</span>
+<span id="L259" rel="#L259">259</span>
+<span id="L260" rel="#L260">260</span>
+<span id="L261" rel="#L261">261</span>
+<span id="L262" rel="#L262">262</span>
+</pre>
+ </td>
+ <td width="100%">
+ <div class="highlight"><pre><div class='line' id='LC1'><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot; ?&gt;</span></div><div class='line' id='LC2'><span class="cp">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span></div><div class='line' id='LC3'><span class="nt">&lt;html</span> <span class="na">xmlns=</span><span class="s">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="nt">&gt;</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="nt">&lt;head&gt;</span></div><div class='line' id='LC6'><span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">&quot;Content-Type&quot;</span> <span class="na">content=</span><span class="s">&quot;text/html; charset=ISO-8859-1&quot;</span> <span class="nt">/&gt;</span></div><div class='line' id='LC7'><span class="nt">&lt;title&gt;</span>Eclipse Public License - Version 1.0<span class="nt">&lt;/title&gt;</span></div><div class='line' id='LC8'><span class="nt">&lt;style </span><span class="na">type=</span><span class="s">&quot;text/css&quot;</span><span class="nt">&gt;</span></div><div class='line' id='LC9'>&nbsp;&nbsp;<span class="nt">body</span> <span class="p">{</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">size</span><span class="o">:</span> <span class="m">8.5in</span> <span class="m">11.0in</span><span class="p">;</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">margin</span><span class="o">:</span> <span class="m">0.25in</span> <span class="m">0.5in</span> <span class="m">0.25in</span> <span class="m">0.5in</span><span class="p">;</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">tab</span><span class="o">-</span><span class="n">interval</span><span class="o">:</span> <span class="m">0.5in</span><span class="p">;</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC14'>&nbsp;&nbsp;<span class="nt">p</span> <span class="p">{</span> </div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">margin-left</span><span class="o">:</span> <span class="k">auto</span><span class="p">;</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">margin-top</span><span class="o">:</span> <span class="m">0.5em</span><span class="p">;</span></div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">margin-bottom</span><span class="o">:</span> <span class="m">0.5em</span><span class="p">;</span></div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC19'>&nbsp;&nbsp;<span class="nt">p</span><span class="nc">.list</span> <span class="p">{</span></div><div class='line' id='LC20'>&nbsp;&nbsp; <span class="k">margin-left</span><span class="o">:</span> <span class="m">0.5in</span><span class="p">;</span></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">margin-top</span><span class="o">:</span> <span class="m">0.05em</span><span class="p">;</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">margin-bottom</span><span class="o">:</span> <span class="m">0.05em</span><span class="p">;</span></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC24'>&nbsp;&nbsp;<span class="nt">&lt;/style&gt;</span></div><div class='line' id='LC25'><br/></div><div class='line' id='LC26'><span class="nt">&lt;/head&gt;</span></div><div class='line' id='LC27'><br/></div><div class='line' id='LC28'><span class="nt">&lt;body</span> <span class="na">lang=</span><span class="s">&quot;EN-US&quot;</span><span class="nt">&gt;</span></div><div class='line' id='LC29'><br/></div><div class='line' id='LC30'><span class="nt">&lt;p</span> <span class="na">align=</span><span class="s">center</span><span class="nt">&gt;&lt;b&gt;</span>Eclipse Public License - v 1.0<span class="nt">&lt;/b&gt;&lt;/p&gt;</span></div><div class='line' id='LC31'><br/></div><div class='line' id='LC32'><span class="nt">&lt;p&gt;</span>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE</div><div class='line' id='LC33'>PUBLIC LICENSE (<span class="ni">&amp;quot;</span>AGREEMENT<span class="ni">&amp;quot;</span>). ANY USE, REPRODUCTION OR</div><div class='line' id='LC34'>DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT&#39;S ACCEPTANCE OF THIS</div><div class='line' id='LC35'>AGREEMENT.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC36'><br/></div><div class='line' id='LC37'><span class="nt">&lt;p&gt;&lt;b&gt;</span>1. DEFINITIONS<span class="nt">&lt;/b&gt;&lt;/p&gt;</span></div><div class='line' id='LC38'><br/></div><div class='line' id='LC39'><span class="nt">&lt;p&gt;</span><span class="ni">&amp;quot;</span>Contribution<span class="ni">&amp;quot;</span> means:<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC40'><br/></div><div class='line' id='LC41'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>a) in the case of the initial Contributor, the initial</div><div class='line' id='LC42'>code and documentation distributed under this Agreement, and<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC43'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>b) in the case of each subsequent Contributor:<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC44'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>i) changes to the Program, and<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC45'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>ii) additions to the Program;<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC46'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>where such changes and/or additions to the Program</div><div class='line' id='LC47'>originate from and are distributed by that particular Contributor. A</div><div class='line' id='LC48'>Contribution &#39;originates&#39; from a Contributor if it was added to the</div><div class='line' id='LC49'>Program by such Contributor itself or anyone acting on such</div><div class='line' id='LC50'>Contributor&#39;s behalf. Contributions do not include additions to the</div><div class='line' id='LC51'>Program which: (i) are separate modules of software distributed in</div><div class='line' id='LC52'>conjunction with the Program under their own license agreement, and (ii)</div><div class='line' id='LC53'>are not derivative works of the Program.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC54'><br/></div><div class='line' id='LC55'><span class="nt">&lt;p&gt;</span><span class="ni">&amp;quot;</span>Contributor<span class="ni">&amp;quot;</span> means any person or entity that distributes</div><div class='line' id='LC56'>the Program.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC57'><br/></div><div class='line' id='LC58'><span class="nt">&lt;p&gt;</span><span class="ni">&amp;quot;</span>Licensed Patents<span class="ni">&amp;quot;</span> mean patent claims licensable by a</div><div class='line' id='LC59'>Contributor which are necessarily infringed by the use or sale of its</div><div class='line' id='LC60'>Contribution alone or when combined with the Program.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC61'><br/></div><div class='line' id='LC62'><span class="nt">&lt;p&gt;</span><span class="ni">&amp;quot;</span>Program<span class="ni">&amp;quot;</span> means the Contributions distributed in accordance</div><div class='line' id='LC63'>with this Agreement.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC64'><br/></div><div class='line' id='LC65'><span class="nt">&lt;p&gt;</span><span class="ni">&amp;quot;</span>Recipient<span class="ni">&amp;quot;</span> means anyone who receives the Program under</div><div class='line' id='LC66'>this Agreement, including all Contributors.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC67'><br/></div><div class='line' id='LC68'><span class="nt">&lt;p&gt;&lt;b&gt;</span>2. GRANT OF RIGHTS<span class="nt">&lt;/b&gt;&lt;/p&gt;</span></div><div class='line' id='LC69'><br/></div><div class='line' id='LC70'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>a) Subject to the terms of this Agreement, each</div><div class='line' id='LC71'>Contributor hereby grants Recipient a non-exclusive, worldwide,</div><div class='line' id='LC72'>royalty-free copyright license to reproduce, prepare derivative works</div><div class='line' id='LC73'>of, publicly display, publicly perform, distribute and sublicense the</div><div class='line' id='LC74'>Contribution of such Contributor, if any, and such derivative works, in</div><div class='line' id='LC75'>source code and object code form.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC76'><br/></div><div class='line' id='LC77'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>b) Subject to the terms of this Agreement, each</div><div class='line' id='LC78'>Contributor hereby grants Recipient a non-exclusive, worldwide,</div><div class='line' id='LC79'>royalty-free patent license under Licensed Patents to make, use, sell,</div><div class='line' id='LC80'>offer to sell, import and otherwise transfer the Contribution of such</div><div class='line' id='LC81'>Contributor, if any, in source code and object code form. This patent</div><div class='line' id='LC82'>license shall apply to the combination of the Contribution and the</div><div class='line' id='LC83'>Program if, at the time the Contribution is added by the Contributor,</div><div class='line' id='LC84'>such addition of the Contribution causes such combination to be covered</div><div class='line' id='LC85'>by the Licensed Patents. The patent license shall not apply to any other</div><div class='line' id='LC86'>combinations which include the Contribution. No hardware per se is</div><div class='line' id='LC87'>licensed hereunder.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC88'><br/></div><div class='line' id='LC89'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>c) Recipient understands that although each Contributor</div><div class='line' id='LC90'>grants the licenses to its Contributions set forth herein, no assurances</div><div class='line' id='LC91'>are provided by any Contributor that the Program does not infringe the</div><div class='line' id='LC92'>patent or other intellectual property rights of any other entity. Each</div><div class='line' id='LC93'>Contributor disclaims any liability to Recipient for claims brought by</div><div class='line' id='LC94'>any other entity based on infringement of intellectual property rights</div><div class='line' id='LC95'>or otherwise. As a condition to exercising the rights and licenses</div><div class='line' id='LC96'>granted hereunder, each Recipient hereby assumes sole responsibility to</div><div class='line' id='LC97'>secure any other intellectual property rights needed, if any. For</div><div class='line' id='LC98'>example, if a third party patent license is required to allow Recipient</div><div class='line' id='LC99'>to distribute the Program, it is Recipient&#39;s responsibility to acquire</div><div class='line' id='LC100'>that license before distributing the Program.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC101'><br/></div><div class='line' id='LC102'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>d) Each Contributor represents that to its knowledge it</div><div class='line' id='LC103'>has sufficient copyright rights in its Contribution, if any, to grant</div><div class='line' id='LC104'>the copyright license set forth in this Agreement.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC105'><br/></div><div class='line' id='LC106'><span class="nt">&lt;p&gt;&lt;b&gt;</span>3. REQUIREMENTS<span class="nt">&lt;/b&gt;&lt;/p&gt;</span></div><div class='line' id='LC107'><br/></div><div class='line' id='LC108'><span class="nt">&lt;p&gt;</span>A Contributor may choose to distribute the Program in object code</div><div class='line' id='LC109'>form under its own license agreement, provided that:<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC110'><br/></div><div class='line' id='LC111'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>a) it complies with the terms and conditions of this</div><div class='line' id='LC112'>Agreement; and<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC113'><br/></div><div class='line' id='LC114'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>b) its license agreement:<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC115'><br/></div><div class='line' id='LC116'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>i) effectively disclaims on behalf of all Contributors</div><div class='line' id='LC117'>all warranties and conditions, express and implied, including warranties</div><div class='line' id='LC118'>or conditions of title and non-infringement, and implied warranties or</div><div class='line' id='LC119'>conditions of merchantability and fitness for a particular purpose;<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC120'><br/></div><div class='line' id='LC121'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>ii) effectively excludes on behalf of all Contributors</div><div class='line' id='LC122'>all liability for damages, including direct, indirect, special,</div><div class='line' id='LC123'>incidental and consequential damages, such as lost profits;<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC124'><br/></div><div class='line' id='LC125'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>iii) states that any provisions which differ from this</div><div class='line' id='LC126'>Agreement are offered by that Contributor alone and not by any other</div><div class='line' id='LC127'>party; and<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC128'><br/></div><div class='line' id='LC129'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>iv) states that source code for the Program is available</div><div class='line' id='LC130'>from such Contributor, and informs licensees how to obtain it in a</div><div class='line' id='LC131'>reasonable manner on or through a medium customarily used for software</div><div class='line' id='LC132'>exchange.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC133'><br/></div><div class='line' id='LC134'><span class="nt">&lt;p&gt;</span>When the Program is made available in source code form:<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC135'><br/></div><div class='line' id='LC136'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>a) it must be made available under this Agreement; and<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC137'><br/></div><div class='line' id='LC138'><span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;list&quot;</span><span class="nt">&gt;</span>b) a copy of this Agreement must be included with each</div><div class='line' id='LC139'>copy of the Program.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC140'><br/></div><div class='line' id='LC141'><span class="nt">&lt;p&gt;</span>Contributors may not remove or alter any copyright notices contained</div><div class='line' id='LC142'>within the Program.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC143'><br/></div><div class='line' id='LC144'><span class="nt">&lt;p&gt;</span>Each Contributor must identify itself as the originator of its</div><div class='line' id='LC145'>Contribution, if any, in a manner that reasonably allows subsequent</div><div class='line' id='LC146'>Recipients to identify the originator of the Contribution.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC147'><br/></div><div class='line' id='LC148'><span class="nt">&lt;p&gt;&lt;b&gt;</span>4. COMMERCIAL DISTRIBUTION<span class="nt">&lt;/b&gt;&lt;/p&gt;</span></div><div class='line' id='LC149'><br/></div><div class='line' id='LC150'><span class="nt">&lt;p&gt;</span>Commercial distributors of software may accept certain</div><div class='line' id='LC151'>responsibilities with respect to end users, business partners and the</div><div class='line' id='LC152'>like. While this license is intended to facilitate the commercial use of</div><div class='line' id='LC153'>the Program, the Contributor who includes the Program in a commercial</div><div class='line' id='LC154'>product offering should do so in a manner which does not create</div><div class='line' id='LC155'>potential liability for other Contributors. Therefore, if a Contributor</div><div class='line' id='LC156'>includes the Program in a commercial product offering, such Contributor</div><div class='line' id='LC157'>(<span class="ni">&amp;quot;</span>Commercial Contributor<span class="ni">&amp;quot;</span>) hereby agrees to defend and</div><div class='line' id='LC158'>indemnify every other Contributor (<span class="ni">&amp;quot;</span>Indemnified Contributor<span class="ni">&amp;quot;</span>)</div><div class='line' id='LC159'>against any losses, damages and costs (collectively <span class="ni">&amp;quot;</span>Losses<span class="ni">&amp;quot;</span>)</div><div class='line' id='LC160'>arising from claims, lawsuits and other legal actions brought by a third</div><div class='line' id='LC161'>party against the Indemnified Contributor to the extent caused by the</div><div class='line' id='LC162'>acts or omissions of such Commercial Contributor in connection with its</div><div class='line' id='LC163'>distribution of the Program in a commercial product offering. The</div><div class='line' id='LC164'>obligations in this section do not apply to any claims or Losses</div><div class='line' id='LC165'>relating to any actual or alleged intellectual property infringement. In</div><div class='line' id='LC166'>order to qualify, an Indemnified Contributor must: a) promptly notify</div><div class='line' id='LC167'>the Commercial Contributor in writing of such claim, and b) allow the</div><div class='line' id='LC168'>Commercial Contributor to control, and cooperate with the Commercial</div><div class='line' id='LC169'>Contributor in, the defense and any related settlement negotiations. The</div><div class='line' id='LC170'>Indemnified Contributor may participate in any such claim at its own</div><div class='line' id='LC171'>expense.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC172'><br/></div><div class='line' id='LC173'><span class="nt">&lt;p&gt;</span>For example, a Contributor might include the Program in a commercial</div><div class='line' id='LC174'>product offering, Product X. That Contributor is then a Commercial</div><div class='line' id='LC175'>Contributor. If that Commercial Contributor then makes performance</div><div class='line' id='LC176'>claims, or offers warranties related to Product X, those performance</div><div class='line' id='LC177'>claims and warranties are such Commercial Contributor&#39;s responsibility</div><div class='line' id='LC178'>alone. Under this section, the Commercial Contributor would have to</div><div class='line' id='LC179'>defend claims against the other Contributors related to those</div><div class='line' id='LC180'>performance claims and warranties, and if a court requires any other</div><div class='line' id='LC181'>Contributor to pay any damages as a result, the Commercial Contributor</div><div class='line' id='LC182'>must pay those damages.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC183'><br/></div><div class='line' id='LC184'><span class="nt">&lt;p&gt;&lt;b&gt;</span>5. NO WARRANTY<span class="nt">&lt;/b&gt;&lt;/p&gt;</span></div><div class='line' id='LC185'><br/></div><div class='line' id='LC186'><span class="nt">&lt;p&gt;</span>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS</div><div class='line' id='LC187'>PROVIDED ON AN <span class="ni">&amp;quot;</span>AS IS<span class="ni">&amp;quot;</span> BASIS, WITHOUT WARRANTIES OR CONDITIONS</div><div class='line' id='LC188'>OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,</div><div class='line' id='LC189'>ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY</div><div class='line' id='LC190'>OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely</div><div class='line' id='LC191'>responsible for determining the appropriateness of using and</div><div class='line' id='LC192'>distributing the Program and assumes all risks associated with its</div><div class='line' id='LC193'>exercise of rights under this Agreement , including but not limited to</div><div class='line' id='LC194'>the risks and costs of program errors, compliance with applicable laws,</div><div class='line' id='LC195'>damage to or loss of data, programs or equipment, and unavailability or</div><div class='line' id='LC196'>interruption of operations.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC197'><br/></div><div class='line' id='LC198'><span class="nt">&lt;p&gt;&lt;b&gt;</span>6. DISCLAIMER OF LIABILITY<span class="nt">&lt;/b&gt;&lt;/p&gt;</span></div><div class='line' id='LC199'><br/></div><div class='line' id='LC200'><span class="nt">&lt;p&gt;</span>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT</div><div class='line' id='LC201'>NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,</div><div class='line' id='LC202'>INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING</div><div class='line' id='LC203'>WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF</div><div class='line' id='LC204'>LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING</div><div class='line' id='LC205'>NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR</div><div class='line' id='LC206'>DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED</div><div class='line' id='LC207'>HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC208'><br/></div><div class='line' id='LC209'><span class="nt">&lt;p&gt;&lt;b&gt;</span>7. GENERAL<span class="nt">&lt;/b&gt;&lt;/p&gt;</span></div><div class='line' id='LC210'><br/></div><div class='line' id='LC211'><span class="nt">&lt;p&gt;</span>If any provision of this Agreement is invalid or unenforceable under</div><div class='line' id='LC212'>applicable law, it shall not affect the validity or enforceability of</div><div class='line' id='LC213'>the remainder of the terms of this Agreement, and without further action</div><div class='line' id='LC214'>by the parties hereto, such provision shall be reformed to the minimum</div><div class='line' id='LC215'>extent necessary to make such provision valid and enforceable.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC216'><br/></div><div class='line' id='LC217'><span class="nt">&lt;p&gt;</span>If Recipient institutes patent litigation against any entity</div><div class='line' id='LC218'>(including a cross-claim or counterclaim in a lawsuit) alleging that the</div><div class='line' id='LC219'>Program itself (excluding combinations of the Program with other</div><div class='line' id='LC220'>software or hardware) infringes such Recipient&#39;s patent(s), then such</div><div class='line' id='LC221'>Recipient&#39;s rights granted under Section 2(b) shall terminate as of the</div><div class='line' id='LC222'>date such litigation is filed.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC223'><br/></div><div class='line' id='LC224'><span class="nt">&lt;p&gt;</span>All Recipient&#39;s rights under this Agreement shall terminate if it</div><div class='line' id='LC225'>fails to comply with any of the material terms or conditions of this</div><div class='line' id='LC226'>Agreement and does not cure such failure in a reasonable period of time</div><div class='line' id='LC227'>after becoming aware of such noncompliance. If all Recipient&#39;s rights</div><div class='line' id='LC228'>under this Agreement terminate, Recipient agrees to cease use and</div><div class='line' id='LC229'>distribution of the Program as soon as reasonably practicable. However,</div><div class='line' id='LC230'>Recipient&#39;s obligations under this Agreement and any licenses granted by</div><div class='line' id='LC231'>Recipient relating to the Program shall continue and survive.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC232'><br/></div><div class='line' id='LC233'><span class="nt">&lt;p&gt;</span>Everyone is permitted to copy and distribute copies of this</div><div class='line' id='LC234'>Agreement, but in order to avoid inconsistency the Agreement is</div><div class='line' id='LC235'>copyrighted and may only be modified in the following manner. The</div><div class='line' id='LC236'>Agreement Steward reserves the right to publish new versions (including</div><div class='line' id='LC237'>revisions) of this Agreement from time to time. No one other than the</div><div class='line' id='LC238'>Agreement Steward has the right to modify this Agreement. The Eclipse</div><div class='line' id='LC239'>Foundation is the initial Agreement Steward. The Eclipse Foundation may</div><div class='line' id='LC240'>assign the responsibility to serve as the Agreement Steward to a</div><div class='line' id='LC241'>suitable separate entity. Each new version of the Agreement will be</div><div class='line' id='LC242'>given a distinguishing version number. The Program (including</div><div class='line' id='LC243'>Contributions) may always be distributed subject to the version of the</div><div class='line' id='LC244'>Agreement under which it was received. In addition, after a new version</div><div class='line' id='LC245'>of the Agreement is published, Contributor may elect to distribute the</div><div class='line' id='LC246'>Program (including its Contributions) under the new version. Except as</div><div class='line' id='LC247'>expressly stated in Sections 2(a) and 2(b) above, Recipient receives no</div><div class='line' id='LC248'>rights or licenses to the intellectual property of any Contributor under</div><div class='line' id='LC249'>this Agreement, whether expressly, by implication, estoppel or</div><div class='line' id='LC250'>otherwise. All rights in the Program not expressly granted under this</div><div class='line' id='LC251'>Agreement are reserved.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC252'><br/></div><div class='line' id='LC253'><span class="nt">&lt;p&gt;</span>This Agreement is governed by the laws of the State of New York and</div><div class='line' id='LC254'>the intellectual property laws of the United States of America. No party</div><div class='line' id='LC255'>to this Agreement will bring a legal action under this Agreement more</div><div class='line' id='LC256'>than one year after the cause of action arose. Each party waives its</div><div class='line' id='LC257'>rights to a jury trial in any resulting litigation.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC258'><br/></div><div class='line' id='LC259'><span class="nt">&lt;/body&gt;</span></div><div class='line' id='LC260'><br/></div><div class='line' id='LC261'><span class="nt">&lt;/html&gt;</span></div><div class='line' id='LC262'><br/></div></pre></div>
+ </td>
+ </tr>
+ </table>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+
+<div class="frame frame-loading" style="display:none;" data-tree-list-url="/clojure/clojurescript/tree-list/13e73bacc3cee2bbdcdce908ad3f48b4a5565d42" data-blob-url-prefix="/clojure/clojurescript/blob/13e73bacc3cee2bbdcdce908ad3f48b4a5565d42">
+ <img src="https://a248.e.akamai.net/assets.github.com/images/modules/ajax/big_spinner_336699.gif?1252203928" height="32" width="32">
+</div>
+
+ </div>
+
+ </div>
+ <!-- footer -->
+ <div id="footer" >
+
+ <div class="upper_footer">
+ <div class="site" class="clearfix">
+
+ <!--[if IE]><h4 id="blacktocat_ie">GitHub Links</h4><![endif]-->
+ <![if !IE]><h4 id="blacktocat">GitHub Links</h4><![endif]>
+
+ <ul class="footer_nav">
+ <h4>GitHub</h4>
+ <li><a href="https://github.com/about">About</a></li>
+ <li><a href="https://github.com/blog">Blog</a></li>
+ <li><a href="https://github.com/features">Features</a></li>
+ <li><a href="https://github.com/contact">Contact &amp; Support</a></li>
+ <li><a href="https://github.com/training">Training</a></li>
+ <li><a href="http://status.github.com/">Site Status</a></li>
+ </ul>
+
+ <ul class="footer_nav">
+ <h4>Tools</h4>
+ <li><a href="http://mac.github.com/">GitHub for Mac</a></li>
+ <li><a href="http://mobile.github.com/">Issues for iPhone</a></li>
+ <li><a href="https://gist.github.com">Gist: Code Snippets</a></li>
+ <li><a href="http://enterprise.github.com/">GitHub Enterprise</a></li>
+ <li><a href="http://jobs.github.com/">Job Board</a></li>
+ </ul>
+
+ <ul class="footer_nav">
+ <h4>Extras</h4>
+ <li><a href="http://shop.github.com/">GitHub Shop</a></li>
+ <li><a href="http://octodex.github.com/">The Octodex</a></li>
+ </ul>
+
+ <ul class="footer_nav">
+ <h4>Documentation</h4>
+ <li><a href="http://help.github.com/">GitHub Help</a></li>
+ <li><a href="http://developer.github.com/">Developer API</a></li>
+ <li><a href="http://github.github.com/github-flavored-markdown/">GitHub Flavored Markdown</a></li>
+ <li><a href="http://pages.github.com/">GitHub Pages</a></li>
+ </ul>
+
+ </div><!-- /.site -->
+ </div><!-- /.upper_footer -->
+
+<div class="lower_footer">
+ <div class="site" class="clearfix">
+ <!--[if IE]><div id="legal_ie"><![endif]-->
+ <![if !IE]><div id="legal"><![endif]>
+ <ul>
+ <li><a href="https://github.com/site/terms">Terms of Service</a></li>
+ <li><a href="https://github.com/site/privacy">Privacy</a></li>
+ <li><a href="https://github.com/security">Security</a></li>
+ </ul>
+
+ <p>&copy; 2011 <span id="_rrt" title="0.10533s from fe3.rs.github.com">GitHub</span> Inc. All rights reserved.</p>
+ </div><!-- /#legal or /#legal_ie-->
+
+ <div class="sponsor">
+ <a href="http://www.rackspace.com" class="logo">
+ <img alt="Dedicated Server" height="36" src="https://a248.e.akamai.net/assets.github.com/images/modules/footer/rackspace_logo.png?v2" width="38" />
+ </a>
+ Powered by the <a href="http://www.rackspace.com ">Dedicated
+ Servers</a> and<br/> <a href="http://www.rackspacecloud.com">Cloud
+ Computing</a> of Rackspace Hosting<span>&reg;</span>
+ </div>
+ </div><!-- /.site -->
+</div><!-- /.lower_footer -->
+
+ </div><!-- /#footer -->
+
+
+
+<div id="keyboard_shortcuts_pane" class="instapaper_ignore readability-extra" style="display:none">
+ <h2>Keyboard Shortcuts <small><a href="#" class="js-see-all-keyboard-shortcuts">(see all)</a></small></h2>
+
+ <div class="columns threecols">
+ <div class="column first">
+ <h3>Site wide shortcuts</h3>
+ <dl class="keyboard-mappings">
+ <dt>s</dt>
+ <dd>Focus site search</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>?</dt>
+ <dd>Bring up this help dialog</dd>
+ </dl>
+ </div><!-- /.column.first -->
+
+ <div class="column middle" style='display:none'>
+ <h3>Commit list</h3>
+ <dl class="keyboard-mappings">
+ <dt>j</dt>
+ <dd>Move selection down</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>k</dt>
+ <dd>Move selection up</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>c <em>or</em> o <em>or</em> enter</dt>
+ <dd>Open commit</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>y</dt>
+ <dd>Expand URL to its canonical form</dd>
+ </dl>
+ </div><!-- /.column.first -->
+
+ <div class="column last" style='display:none'>
+ <h3>Pull request list</h3>
+ <dl class="keyboard-mappings">
+ <dt>j</dt>
+ <dd>Move selection down</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>k</dt>
+ <dd>Move selection up</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>o <em>or</em> enter</dt>
+ <dd>Open issue</dd>
+ </dl>
+ </div><!-- /.columns.last -->
+
+ </div><!-- /.columns.equacols -->
+
+ <div style='display:none'>
+ <div class="rule"></div>
+
+ <h3>Issues</h3>
+
+ <div class="columns threecols">
+ <div class="column first">
+ <dl class="keyboard-mappings">
+ <dt>j</dt>
+ <dd>Move selection down</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>k</dt>
+ <dd>Move selection up</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>x</dt>
+ <dd>Toggle selection</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>o <em>or</em> enter</dt>
+ <dd>Open issue</dd>
+ </dl>
+ </div><!-- /.column.first -->
+ <div class="column middle">
+ <dl class="keyboard-mappings">
+ <dt>I</dt>
+ <dd>Mark selection as read</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>U</dt>
+ <dd>Mark selection as unread</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>e</dt>
+ <dd>Close selection</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>y</dt>
+ <dd>Remove selection from view</dd>
+ </dl>
+ </div><!-- /.column.middle -->
+ <div class="column last">
+ <dl class="keyboard-mappings">
+ <dt>c</dt>
+ <dd>Create issue</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>l</dt>
+ <dd>Create label</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>i</dt>
+ <dd>Back to inbox</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>u</dt>
+ <dd>Back to issues</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>/</dt>
+ <dd>Focus issues search</dd>
+ </dl>
+ </div>
+ </div>
+ </div>
+
+ <div style='display:none'>
+ <div class="rule"></div>
+
+ <h3>Issues Dashboard</h3>
+
+ <div class="columns threecols">
+ <div class="column first">
+ <dl class="keyboard-mappings">
+ <dt>j</dt>
+ <dd>Move selection down</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>k</dt>
+ <dd>Move selection up</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>o <em>or</em> enter</dt>
+ <dd>Open issue</dd>
+ </dl>
+ </div><!-- /.column.first -->
+ </div>
+ </div>
+
+ <div style='display:none'>
+ <div class="rule"></div>
+
+ <h3>Network Graph</h3>
+ <div class="columns equacols">
+ <div class="column first">
+ <dl class="keyboard-mappings">
+ <dt><span class="badmono">←</span> <em>or</em> h</dt>
+ <dd>Scroll left</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt><span class="badmono">→</span> <em>or</em> l</dt>
+ <dd>Scroll right</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt><span class="badmono">↑</span> <em>or</em> k</dt>
+ <dd>Scroll up</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt><span class="badmono">↓</span> <em>or</em> j</dt>
+ <dd>Scroll down</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>t</dt>
+ <dd>Toggle visibility of head labels</dd>
+ </dl>
+ </div><!-- /.column.first -->
+ <div class="column last">
+ <dl class="keyboard-mappings">
+ <dt>shift <span class="badmono">←</span> <em>or</em> shift h</dt>
+ <dd>Scroll all the way left</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>shift <span class="badmono">→</span> <em>or</em> shift l</dt>
+ <dd>Scroll all the way right</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>shift <span class="badmono">↑</span> <em>or</em> shift k</dt>
+ <dd>Scroll all the way up</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>shift <span class="badmono">↓</span> <em>or</em> shift j</dt>
+ <dd>Scroll all the way down</dd>
+ </dl>
+ </div><!-- /.column.last -->
+ </div>
+ </div>
+
+ <div >
+ <div class="rule"></div>
+ <div class="columns threecols">
+ <div class="column first" >
+ <h3>Source Code Browsing</h3>
+ <dl class="keyboard-mappings">
+ <dt>t</dt>
+ <dd>Activates the file finder</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>l</dt>
+ <dd>Jump to line</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>w</dt>
+ <dd>Switch branch/tag</dd>
+ </dl>
+ <dl class="keyboard-mappings">
+ <dt>y</dt>
+ <dd>Expand URL to its canonical form</dd>
+ </dl>
+ </div>
+ </div>
+ </div>
+</div>
+
+ <div id="markdown-help" class="instapaper_ignore readability-extra">
+ <h2>Markdown Cheat Sheet</h2>
+
+ <div class="cheatsheet-content">
+
+ <div class="mod">
+ <div class="col">
+ <h3>Format Text</h3>
+ <p>Headers</p>
+ <pre>
+# This is an &lt;h1&gt; tag
+## This is an &lt;h2&gt; tag
+###### This is an &lt;h6&gt; tag</pre>
+ <p>Text styles</p>
+ <pre>
+*This text will be italic*
+_This will also be italic_
+**This text will be bold**
+__This will also be bold__
+
+*You **can** combine them*
+</pre>
+ </div>
+ <div class="col">
+ <h3>Lists</h3>
+ <p>Unordered</p>
+ <pre>
+* Item 1
+* Item 2
+ * Item 2a
+ * Item 2b</pre>
+ <p>Ordered</p>
+ <pre>
+1. Item 1
+2. Item 2
+3. Item 3
+ * Item 3a
+ * Item 3b</pre>
+ </div>
+ <div class="col">
+ <h3>Miscellaneous</h3>
+ <p>Images</p>
+ <pre>
+![GitHub Logo](/images/logo.png)
+Format: ![Alt Text](url)
+</pre>
+ <p>Links</p>
+ <pre>
+http://github.com - automatic!
+[GitHub](http://github.com)</pre>
+<p>Blockquotes</p>
+ <pre>
+As Kanye West said:
+> We're living the future so
+> the present is our past.
+</pre>
+ </div>
+ </div>
+ <div class="rule"></div>
+
+ <h3>Code Examples in Markdown</h3>
+ <div class="col">
+ <p>Syntax highlighting with <a href="http://github.github.com/github-flavored-markdown/" title="GitHub Flavored Markdown" target="_blank">GFM</a></p>
+ <pre>
+```javascript
+function fancyAlert(arg) {
+ if(arg) {
+ $.facebox({div:'#foo'})
+ }
+}
+```</pre>
+ </div>
+ <div class="col">
+ <p>Or, indent your code 4 spaces</p>
+ <pre>
+Here is a Python code example
+without syntax highlighting:
+
+ def foo:
+ if not bar:
+ return true</pre>
+ </div>
+ <div class="col">
+ <p>Inline code for comments</p>
+ <pre>
+I think you should use an
+`&lt;addr&gt;` element here instead.</pre>
+ </div>
+ </div>
+
+ </div>
+</div>
+
+ <div class="context-overlay"></div>
+
+ <div class="ajax-error-message">
+ <p><span class="icon"></span> Something went wrong with that request. Please try again. <a href="javascript:;" class="ajax-error-dismiss">Dismiss</a></p>
+ </div>
+
+
+
+
+ </body>
+</html>
+
View
124 lib/channels.js
@@ -1,79 +1,54 @@
var redis = require('redis');
Rx = require('rx').Rx;
-// Message Utility Functions
-
-/**
- * Convert an array to a delimited string
- * @param {String []} fields
- * @param {String} delimiter
- * @return {String} delimit string
- */
-function implode(fields, delimiter) {
- var result;
- for (var i in fields) {
- var part = fields[i];
- result = result ? result + delimiter + part : part;
- }
- return result;
-}
-
-/**
- * Creates a namespace string for redis objects
- */
-function ns(parts){
- var args = Array.prototype.slice.call(arguments);
- return implode(args, '.');
-}
-
-exports.ns = ns;
+// contsants
+// Well known message to close a channel
+var CLOSE_MSG = 'QRX-close';
/**
* Creates an observable redis channel
- * @param {String} name channel name
+ * @param {String} ch channel name
* @param {Object} [redisOpts] redis connection options
* @return {Rx.Observable}
*/
-function createObservableChannel(name, redisOpts) {
- var ch = redisOpts ?
- redis.createClient(redisOpts.port, redisOpts.host, redisOpts):
- redis.createClient();
-
- return Rx.Observable.Create(function(obs){
- ch.on("message", function(channel, msg) {
- obs.OnNext(msg);
+function createObservableChannel(ch, redisOpts) {
+ // subscribtion have to create their own
+ // redis connection as the connection can
+ // only be used for pub/sub when 'SUBSCRIBE'
+ // is invoked
+ var client = redisOpts ?
+ redis.createClient(redisOpts.port, redisOpts.host, redisOpts):
+ redis.createClient();
+
+ return Rx.Observable.Create(function(obs){
+ client.on("message", function(channel, msg) {
+ if (msg == CLOSE_MSG){
+ obs.OnCompleted();
+ } else {
+ obs.OnNext(msg);
+ }
+ });
+ client.subscribe(ch);
+ return function(){client.end();};
});
- ch.subscribe(name);
- return function(){ch.end();};
- })
}
exports.createObservableChannel = createObservableChannel;
-// Convenience functions for message pack/unpack
+// wrapper functions around redis PUB/SUB
/**
- * Creates a workItem message
- * @param {String} prefix
- * @param {Object} msg message
- * @return {String} work message
+ * @param {redis.RedisClient} client
+ * @param {String} ch channel name
+ * @param {String} msg
+ * @param {function} callback
*/
-function packMsg(prefix, msg){
- return prefix + '#' + JSON.stringify(msg);
+function sendMessage(client, ch, msg, callback){
+ client.publish(ch, msg, callback);
}
-/**
- * Unpacks a workItem from a message
- * @param {String} workMsg
- * @return {Object} workItem
- */
-function unpackMsg(workMsg) {
- var fields = workMsg.split('#');
- var msg = JSON.parse(fields[1]);
- return msg;
-}
+exports.sendMessage = sendMessage;
-var QRX_PREFIX = 'QRX';
function Channel(channelName, redisOptions){
// messages
@@ -82,19 +57,15 @@ function Channel(channelName, redisOptions){
// method available on redisClient
var client = redisOpts ? redis.createClient(redisOpts) :
redis.createClient();
-
+
var redisOpts = redisOptions;
- var ch = ns(QRX_PREFIX, channelName);
+ var ch = channelName;
this.redisObjects = {channel: ch};
-
- var MSG_PREFIX = ns(QRX_PREFIX, channelName);
-
- var CLOSE_MSG = 'close-' + ch;
-
+
this.sendMessage = function(msg, callback){
- client.publish(ch, packMsg(MSG_PREFIX, msg), callback);
+ sendMessage(client, ch, msg, callback);
}
/**
@@ -105,28 +76,11 @@ function Channel(channelName, redisOptions){
this.sendMessage(CLOSE_MSG, function(e,o){});
}
-
+ /**
+ * creates an observable based on the wrapped redis channel
+ */
this.asObservable = function() {
- // subscribtion have to create their own
- // redis connection as the connection can
- // only be used for pub/sub when 'SUBSCRIBE'
- // is invoked
- var client = redisOpts ?
- redis.createClient(redisOpts.port, redisOpts.host, redisOpts):
- redis.createClient();
-
- return Rx.Observable.Create(function(obs){
- client.on("message", function(channel, msgStr) {
- var msg = unpackMsg(msgStr);
- if (msg == CLOSE_MSG){
- obs.OnCompleted();
- } else {
- obs.OnNext(msg);
- }
- });
- client.subscribe(ch);
- return function(){client.end();};
- });
+ return createObservableChannel(ch, redisOpts)
}
}
View
63 lib/qrx.js
@@ -7,10 +7,18 @@ var work = require('./work.js'),
WorkQueue = work.WorkQueue,
WorkSet = work.WorkSet;
cloneCompleted = work.cloneCompleted;
+ enqueue = work.enqueue;
+ dequeue = work.dequeue;
+ drainRx = work.drainRx;
var channels = require('./channels.js'),
- Channel = channels.Channel,
- ns = channels.ns;
+ Channel = channels.Channel;
+ sendMessage = channels.sendMessage;
+ createObservableChannel = channels.createObservableChannel;
+
+var messaging = require('./messaging.js');
+ qrxChannelName = messaging.qrxChannelName,
+ ns = messaging.ns;
/**
* Creates a callback function for completed work, closing in queue env
@@ -46,21 +54,16 @@ function WorkQueueRx(qname, redisOpts) {
var working = new WorkSet(ns(qname, 'working'), this.redis);
// channels
- var workChannel = new Channel(ns(qname, 'work'));
-
-
+ var workChannel = new Channel(qrxChannelName(qname, 'work'));
// unique id for this client instance
// any work send on the workChannel will be stamped with
// the client id
- var clientId = uuid.v1();
- // client-side
- var completedChannel = new Channel(ns(qname, 'completed'));
- // dedicated queu and
- var completed = new WorkQueue(ns(qname, 'completed'), this.redis);
+ var clientId = uuid.v1();
+ this.completedChannelName = qrxChannelName(qname, 'completed') + clientId;
+ this.completedQueueName = ns(qname, 'completed') + clientId;
-
// ToDo: for every client set a channel and make the
// the channels dynamic so that workers can broadcast
// to multiple clients
@@ -69,9 +72,7 @@ function WorkQueueRx(qname, redisOpts) {
// dictionary of redis objects for debugging
this.redisObjects = {pending:pending.redisObjects,
working:working.redisObjects,
- completed:completed.redisObjects,
- workChannel:workChannel.redisObjects,
- completedChannel:completedChannel.redisObjects};
+ workChannel:workChannel.redisObjects};
/**
@@ -94,19 +95,23 @@ function WorkQueueRx(qname, redisOpts) {
*/
this.enqueue = function(work) {
// push onto the queue
- pending.enqueue(work, function(err, workItem){
+ // work contains by name, where completed work should
+ var workItem = new WorkItem(work, this.completedQueueName, this.completedChannelName);
+ pending.enqueue(workItem, function(err, workItem){
if (!err){
// signal waiting workers of new work in queue
- workChannel.sendMessage({id:workItem.id, status:'pending'});
+ workChannel.sendMessage(workItem.id + '-pending');
}
});
};
/**
* Returns the observable of completed work items
+ * from the clients completed queue, signaled on the completed channel
* @return {Rx.Observable}
*/
this.completedObservable = function() {
+ var self = this;
var heartBeat = Rx.Observable.Interval(1000);
// snapshot train of any pending work
function unpackCompletedWork(completedWorkItem){
@@ -117,19 +122,20 @@ function WorkQueueRx(qname, redisOpts) {
error:completedWorkItem.error} ;
}
- var pendingCompleted = completed.drainRx().Select(function(completedWorkItem){
- return unpackCompletedWork(completedWorkItem);
- });
+ var pendingCompleted = drainRx(this.redis, this.completedQueueName)
+ .Select(function(completedWorkItem){
+ return unpackCompletedWork(completedWorkItem);
+ });
// signaled pending work
// project the work messages onto work, onto reactive dequeues
- var workStream = workChannel.asObservable().Merge(heartBeat)
- .SelectMany(function(_){
- return pendingCompleted;
- });
+ var workStream = createObservableChannel(self.completedChannelName)
+ .Merge(heartBeat)
+ .SelectMany(function(_){
+ return pendingCompleted;
+ });
-
// pending will be hot, so will be handled mostly
// ahead of new work
return workStream;
@@ -164,12 +170,12 @@ function WorkQueueRx(qname, redisOpts) {
this.markWorkCompleted = function(workItem, completedWorkItem, callback) {
// TODO: Set a redis transaction
+ var self = this;
working.removeFromSet(workItem.id, function(err, _){
if (!err){
- completed.enqueue(completedWorkItem, function(err, _){
+ enqueue(self.redis, workItem.completedWorkQueue, completedWorkItem, function(err, _){
if (!err) {
- completedChannel.sendMessage({id:completedWorkItem.id,
- status:completedWorkItem.status});
+ sendMessage(self.redis, workItem.completedWorkChannel, workItem.id + '-item_completed');
} else {
// redis err
}
@@ -191,7 +197,7 @@ function WorkQueueRx(qname, redisOpts) {
if (!err){
if (workItem){
// signal waiting workers of new work in queue
- workChannel.sendMessage({id:workItem.id, status:'working'}, function(e,o){});
+ workChannel.sendMessage(workItem.id + '-working', function(e,o){});
// callers get only the information they need
var workObj = {work: workItem.work,
callback: callbackFn(self, workItem)};
@@ -253,7 +259,6 @@ function WorkQueueRx(qname, redisOpts) {
this.clear = function(){
pending.empty();
working.empty();
- completed.empty();
}
}
View
195 lib/work.js
@@ -1,31 +1,122 @@
var redis = require('redis'),
Rx = require('rx').Rx;
uuid = require('node-uuid');
+
+
/**
* @constructor
* Primative work datum with guaranteed unique id
* @param {Object} work
*/
// instance + sequence id
-
-function WorkItem(work){
+function WorkItem(work, completedWorkQueue, completedWorkChannel){
this.id = uuid.v1();
-
this.work = work;
// completed state
this.status = null;
this.completedWork = null;
this.error = null;
+ this.completedWorkQueue = completedWorkQueue;
+ this.completedWorkChannel = completedWorkChannel;
+}
+
+
+
+/////////////////////////////////////////////////////////
+// wrapper function for redis list to simulate a queue //
+function enqueue(client, q, item, callback){
+ var workItem;
+ if (item instanceof WorkItem){
+ workItem = item
+ } else {
+ var workItem = new WorkItem(item);
+ }
+ client.rpush(q, JSON.stringify(workItem), function(err, length){
+ if (!err) {
+ callback(null, {id:workItem.id, queueLength:length});
+ } else {
+ // redis error
+ callback(err);
+ }
+ });
+}
+
+exports.enqueue = enqueue;
+
+function dequeue(client, q, callback){
+ client.lpop(q, function(err, workItemStr){
+ if (!err){
+ callback(null, JSON.parse(workItemStr));
+ } else {
+ callback(err);
+ }
+ });
}
-function cloneCompleted(workItem, err, completedWork){
+exports.dequeue = dequeue;
+
+function dequeueRx(client, q){
+ return Rx.Observable.Create(function(obs){
+ dequeue(client, q, function(err, item){
+ if (!err){
+ if (item){
+ obs.OnNext(item);
+ }
+ // complete with no next is empty
+ obs.OnCompleted();
+ } else {
+ obs.OnError(err);
+ }
+ })
+ return function(){};
+ });
+}
+
+exports.dequeueRx = dequeueRx;
+
+function drainRx(client, q) {
+ return Rx.Observable.Create(function(obs){
+ // snapshot the current queue length
+ client.llen(q, function(err, length){
+ // for as max as we have read length
+ // reactively dequeu, assuming other workers
+ // are also dequeuing
+ var count = length;
+ if (!err) {
+ Rx.Observable.While(
+ function(){return count-- > 0;},
+ // apply a minimum time spacing
+ dequeueRx(client, q)
+ ).Subscribe(function(workItem){
+ obs.OnNext(workItem);
+ });
+ } else {
+ obs.OnError(err);
+ }
+ });
+ return function(){};
+ });
+}
+exports.drainRx = drainRx;
+function empty(client, q, callback){
+ client.del(q, callback);
+}
+
+
+function cloneCompleted(workItem,
+ err,
+ completedWork,
+ completedWorkQueue,
+ completedWorkChannel){
var newWorkItem = new WorkItem(null);
newWorkItem.id = workItem.id;
newWorkItem.work = workItem.work;
newWorkItem.status = err ? 'error' : 'completed'
newWorkItem.completedWork = completedWork;
newWorkItem.error = err;
+ newWorkItem.completedWorkQueue = completedWorkQueue;
+ newWorkItem.completedWorkChannel = completedWorkChannel;
return newWorkItem;
}
exports.cloneCompleted = cloneCompleted;
@@ -53,32 +144,14 @@ function WorkQueue(qname, redisClient) {
* @param {Function} callback
*/
this.enqueue = function(item, callback){
- if (item instanceof WorkItem){
- workItem = item
- } else {
- var workItem = new WorkItem(item);
- }
- client.rpush(q, JSON.stringify(workItem), function(err, length){
- if (!err) {
- callback(null, {id:workItem.id, queueLength:length});
- } else {
- // redis error
- callback(err);
- }
- });
+ enqueue(client, q, item, callback);
}
/**
* @param {Function} callback with head WorkItem
*/
this.dequeue = function(callback){
- client.lpop(q, function(err, workItemStr){
- if (!err){
- callback(null, JSON.parse(workItemStr));
- } else {
- callback(err);
- }
- });
+ return dequeue(client, q, callback);
}
/**
@@ -92,58 +165,22 @@ function WorkQueue(qname, redisClient) {
* Empties the queue of all items
*/
this.empty = function(callback){
- client.del(q, callback);
+ empty(client, q, callback);
}
/**
* Returns an observable to the head of a q
* @return {Rx.Observable} of WorkItem(s)
*/
this.dequeueRx = function() {
- var self = this;
- return Rx.Observable.Create(function(obs){
- self.dequeue(function(err, item){
- if (!err){
- if (item){
- obs.OnNext(item);
- }
- // complete with no next is empty
- obs.OnCompleted();
- } else {
- obs.OnError(err);
- }
- })
- return function(){};
- });
+ return dequeueRx(client, q);
}
/**
* Co-operative 1-time dequeue
* @return {Rx.Observable}
*/
this.drainRx = function(){
- var self = this;
- var rc = client;
- return Rx.Observable.Create(function(obs){
- // snapshot the current queue length
- rc.llen(q, function(err, length){
- // for as max as we have read length
- // reactively dequeu, assuming other workers
- // are also dequeuing
- var count = length;
- if (!err) {
- Rx.Observable.While(
- function(){return count-- > 0;},
- // apply a minimum time spacing
- self.dequeueRx()
- ).Subscribe(function(workItem){
- obs.OnNext(workItem);
- });
- } else {
- obs.OnError(err);
- }
- });
- return function(){};
- });
+ return drainRx(client, q);
}
}
@@ -202,35 +239,3 @@ function WorkSet(setName, redisClient) {
exports.WorkSet = WorkSet;
-
-/**
- * Returns an observable that attempts to empty
- * q from the current time t, assuming other consumers
- * @param {redis.RedisClient} client
- * @param {String} q name
- * @return {Rx.Observable} of WorkItems
- */
-function drainQueueRx(client, q){
- return Rx.Observable.Create(function(obs){
- // snapshot the current queue length
- client.llength(q, function(err, length){
- // for as max as we have read length
- // reactively dequeu, assuming other workers
- // are also dequeuing
- var count = length;
- if (!err) {
- Rx.Observable.While(
- function(){return count-- >= 0;},
- dequeueRx(client, q)
- )
- } else {
- obs.OnError(err);
- }
- });
- return function(){};
- })
- // filter for blanks as others may have
- // drained ahead
- .Where(function(item){return item != null;});
-}
-exports.drainQueueRx = drainQueueRx;
View
33 test/qrx-test.js
@@ -7,7 +7,8 @@ exports.testWorkQueueRx = function(beforeExit, assert) {
var wq = new WorkQueueRx('clean-test');
wq.clear();
- var WORK_COUNT = 500
+ var WORK_COUNT = 500;
+ console.log('Test WorkCount', WORK_COUNT);
for(var i=0; i < WORK_COUNT; i++){
wq.enqueue(i);
}
@@ -31,23 +32,34 @@ exports.testWorkQueueRx = function(beforeExit, assert) {
}
-exports.testWorkQueueRx = function(beforeExit, assert) {
- var wq = new WorkQueueRx('clean-test');
- wq.clear();
- var WORK_COUNT = 500
+exports.multiWorkQueueRx = function(beforeExit, assert) {
+ var wqMaster = new WorkQueueRx('clean-test2');
+ wqMaster.clear();
+
+ var WORK_COUNT = 500;
+ console.log('Test WorkCount', WORK_COUNT);
for(var i=0; i < WORK_COUNT; i++){
- wq.enqueue(i);
+ wqMaster.enqueue(i);
}
+ // two slaves serving 1 master
var workReceived = 0;
- wq.workObservable().Subscribe(function(workObj){
+ var slave1 = new WorkQueueRx('clean-test2');
+ slave1.workObservable().Subscribe(function(workObj){
workReceived++;
workObj.callback(null, workObj.work + 3);
});
-
+
+ var slave2 = new WorkQueueRx('clean-test2');
+ slave2.workObservable().Subscribe(function(workObj){
+ workReceived++;
+ workObj.callback(null, workObj.work + 3);
+ });
+
+ // master get's his work
var completedWorkCount = 0;
- wq.completedObservable().Subscribe(function(completedWork){
+ wqMaster.completedObservable().Subscribe(function(completedWork){
completedWorkCount++;
assert.equal((completedWork.completedWork - completedWork.work) == 3, true);
})
@@ -58,8 +70,7 @@ exports.testWorkQueueRx = function(beforeExit, assert) {
})
}
-
-setTimeout(function(){process.exit(0)}, 2000);
+setTimeout(function(){process.exit(0)}, 5000);
View
18 test/work-test.js
@@ -60,6 +60,24 @@ exports.testWorkItemEnqueue = function(beforeExit, assert){
}
+exports.testWorkItemEmpty = function(beforeExit, assert){
+ var wq = new WorkQueue(uuid.v1(), rc);
+ var testItem = new WorkItem('foo');
+ wq.enqueue(testItem, function(e,o){
+ assert.isNull(e);
+ wq.queueLength(function(e,l){
+ assert.equal(l,1);
+ });
+ wq.empty(function(e, _){
+ assert.isNull(e);
+ wq.queueLength(function(e, l){
+ assert.equal(l,0);
+ });
+ });
+ });
+}
+
+
exports.testWorkSet = function(beforeExit, assert){
var wi = new WorkItem('foo');
var testSet = new WorkSet(uuid.v1(), rc);

0 comments on commit 4edc092

Please sign in to comment.