<!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>[185780] trunk/PerformanceTests</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://trac.webkit.org/projects/webkit/changeset/185780">185780</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-06-19 16:49:38 -0700 (Fri, 19 Jun 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>JetStream should include a JavaScript version of the CDx real-time benchmark
https://bugs.webkit.org/show_bug.cgi?id=146156

Reviewed by Geoffrey Garen.
        
This adds a JavaScript port of the CDx real-time benchmark to JetStream, and retires
the cordic test because it was previously the smallest and probably least interesting.
        
The new test, &quot;cdjs&quot;, is mostly a faithful rewrite of the Java code into JavaScript.
I got the Java code from https://www.cs.purdue.edu/sss/projects/cdx/.
        
There are some differences:
        
- It uses RedBlackTree's for all sets and maps rather than hashtables. This is clearly
  more in the spirit of real-time than the CDx benchmark. FWIW, CDx used to use trees
  and I don't know why that changed in the latest version.
        
- CDjs doesn't attempt to avoid memory allocations, unlike the real-time Java version.
  I wrote the code that I wanted to write for aesthetics, rather than the code that I
  would have written if I tried to write the fastest code possible. Again, I believe
  that this is in the spirit of CDj - it's meant to test what would happen if you wrote
  real-timey stuff in a high level language and actually took advantage of that
  language to be more productive.
        
The test score reflects the average latency of the worst 10 samples out of 200 samples.
The simulation uses 1000 aircraft, flying along paths that result in some detected
collisions every once in a while. The benchmark validates its results by checking the
total number of collisions detected.
        
Apart from the integration into the JetStream harness, the CDjs directory contains a
fully self-contained benchmark that could be run either in the jsc shell or in browser.
        
This new code uses the same 3-clause BSD license as the Purdue code, and gives
attribution to Purdue in almost all files. I believe that is appropriate since I wrote
most of the JS files by looking at the Purdue Java code and trascribing to JavaScript.
In some cases, I even copy-pasted the Java code, like the complicated math for
four-dimensional intersections and voxel hashing.

* JetStream/CDjsSetup.js: Added.
* JetStream/Octane2Setup.js:
* JetStream/Reference.js:
* JetStream/cdjs: Added.
* JetStream/cdjs/benchmark.js: Added.
(benchmark):
* JetStream/cdjs/call_sign.js: Added.
(CallSign):
(CallSign.prototype.compareTo):
(CallSign.prototype.toString):
* JetStream/cdjs/collision.js: Added.
(Collision):
(Collision.prototype.toString):
* JetStream/cdjs/collision_detector.js: Added.
(CollisionDetector):
(CollisionDetector.prototype.handleNewFrame.get for):
(CollisionDetector.prototype.handleNewFrame):
* JetStream/cdjs/constants.js: Added.
* JetStream/cdjs/main.html: Added.
* JetStream/cdjs/main.js: Added.
* JetStream/cdjs/motion.js: Added.
(Motion):
(Motion.prototype.toString):
(Motion.prototype.delta):
(Motion.prototype.findIntersection):
* JetStream/cdjs/motion_test.js: Added.
(checkDoesIntersect):
(checkDoesNotIntersect):
(makeMotion):
* JetStream/cdjs/red_black_tree.js: Added.
(RedBlackTree):
(RedBlackTree.):
* JetStream/cdjs/red_black_tree_test.js: Added.
(test):
(test.):
* JetStream/cdjs/reduce_collision_set.js: Added.
(drawMotionOnVoxelMap):
(drawMotionOnVoxelMap.):
(.get reduceCollisionSet):
* JetStream/cdjs/reduce_collision_set_test.js: Added.
(makeMotion):
(keys):
(test):
* JetStream/cdjs/simulator.js: Added.
(Simulator):
(Simulator.prototype.simulate):
* JetStream/cdjs/util.js: Added.
(compareNumbers):
(averageAbovePercentile):
(currentTime):
(else.currentTime):
* JetStream/cdjs/vector_2d.js: Added.
(Vector2D):
(Vector2D.prototype.plus):
(Vector2D.prototype.minus):
(Vector2D.prototype.toString):
(Vector2D.prototype.compareTo):
* JetStream/cdjs/vector_3d.js: Added.
(Vector3D):
(Vector3D.prototype.plus):
(Vector3D.prototype.minus):
(Vector3D.prototype.dot):
(Vector3D.prototype.squaredMagnitude):
(Vector3D.prototype.magnitude):
(Vector3D.prototype.times):
(Vector3D.prototype.as2D):
(Vector3D.prototype.toString):
* JetStream/create.rb:
* JetStream/index-TEMPLATE.html:
* JetStream/sunspider/cordic.js: Removed.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkPerformanceTestsChangeLog">trunk/PerformanceTests/ChangeLog</a></li>
<li><a href="#trunkPerformanceTestsJetStreamOctane2Setupjs">trunk/PerformanceTests/JetStream/Octane2Setup.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamReferencejs">trunk/PerformanceTests/JetStream/Reference.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcreaterb">trunk/PerformanceTests/JetStream/create.rb</a></li>
<li><a href="#trunkPerformanceTestsJetStreamindexTEMPLATEhtml">trunk/PerformanceTests/JetStream/index-TEMPLATE.html</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkPerformanceTestsJetStreamCDjsSetupjs">trunk/PerformanceTests/JetStream/CDjsSetup.js</a></li>
<li>trunk/PerformanceTests/JetStream/cdjs/</li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsbenchmarkjs">trunk/PerformanceTests/JetStream/cdjs/benchmark.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjscall_signjs">trunk/PerformanceTests/JetStream/cdjs/call_sign.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjscollisionjs">trunk/PerformanceTests/JetStream/cdjs/collision.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjscollision_detectorjs">trunk/PerformanceTests/JetStream/cdjs/collision_detector.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsconstantsjs">trunk/PerformanceTests/JetStream/cdjs/constants.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsmainhtml">trunk/PerformanceTests/JetStream/cdjs/main.html</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsmainjs">trunk/PerformanceTests/JetStream/cdjs/main.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsmotionjs">trunk/PerformanceTests/JetStream/cdjs/motion.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsmotion_testjs">trunk/PerformanceTests/JetStream/cdjs/motion_test.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsred_black_treejs">trunk/PerformanceTests/JetStream/cdjs/red_black_tree.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsred_black_tree_testjs">trunk/PerformanceTests/JetStream/cdjs/red_black_tree_test.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsreduce_collision_setjs">trunk/PerformanceTests/JetStream/cdjs/reduce_collision_set.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsreduce_collision_set_testjs">trunk/PerformanceTests/JetStream/cdjs/reduce_collision_set_test.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjssimulatorjs">trunk/PerformanceTests/JetStream/cdjs/simulator.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsutiljs">trunk/PerformanceTests/JetStream/cdjs/util.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsvector_2djs">trunk/PerformanceTests/JetStream/cdjs/vector_2d.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcdjsvector_3djs">trunk/PerformanceTests/JetStream/cdjs/vector_3d.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkPerformanceTestsJetStreamsunspidercordicjs">trunk/PerformanceTests/JetStream/sunspider/cordic.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkPerformanceTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/ChangeLog (185779 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/ChangeLog        2015-06-19 23:45:35 UTC (rev 185779)
+++ trunk/PerformanceTests/ChangeLog        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -1,3 +1,114 @@
</span><ins>+2015-06-19  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        JetStream should include a JavaScript version of the CDx real-time benchmark
+        https://bugs.webkit.org/show_bug.cgi?id=146156
+
+        Reviewed by Geoffrey Garen.
+        
+        This adds a JavaScript port of the CDx real-time benchmark to JetStream, and retires
+        the cordic test because it was previously the smallest and probably least interesting.
+        
+        The new test, &quot;cdjs&quot;, is mostly a faithful rewrite of the Java code into JavaScript.
+        I got the Java code from https://www.cs.purdue.edu/sss/projects/cdx/.
+        
+        There are some differences:
+        
+        - It uses RedBlackTree's for all sets and maps rather than hashtables. This is clearly
+          more in the spirit of real-time than the CDx benchmark. FWIW, CDx used to use trees
+          and I don't know why that changed in the latest version.
+        
+        - CDjs doesn't attempt to avoid memory allocations, unlike the real-time Java version.
+          I wrote the code that I wanted to write for aesthetics, rather than the code that I
+          would have written if I tried to write the fastest code possible. Again, I believe
+          that this is in the spirit of CDj - it's meant to test what would happen if you wrote
+          real-timey stuff in a high level language and actually took advantage of that
+          language to be more productive.
+        
+        The test score reflects the average latency of the worst 10 samples out of 200 samples.
+        The simulation uses 1000 aircraft, flying along paths that result in some detected
+        collisions every once in a while. The benchmark validates its results by checking the
+        total number of collisions detected.
+        
+        Apart from the integration into the JetStream harness, the CDjs directory contains a
+        fully self-contained benchmark that could be run either in the jsc shell or in browser.
+        
+        This new code uses the same 3-clause BSD license as the Purdue code, and gives
+        attribution to Purdue in almost all files. I believe that is appropriate since I wrote
+        most of the JS files by looking at the Purdue Java code and trascribing to JavaScript.
+        In some cases, I even copy-pasted the Java code, like the complicated math for
+        four-dimensional intersections and voxel hashing.
+
+        * JetStream/CDjsSetup.js: Added.
+        * JetStream/Octane2Setup.js:
+        * JetStream/Reference.js:
+        * JetStream/cdjs: Added.
+        * JetStream/cdjs/benchmark.js: Added.
+        (benchmark):
+        * JetStream/cdjs/call_sign.js: Added.
+        (CallSign):
+        (CallSign.prototype.compareTo):
+        (CallSign.prototype.toString):
+        * JetStream/cdjs/collision.js: Added.
+        (Collision):
+        (Collision.prototype.toString):
+        * JetStream/cdjs/collision_detector.js: Added.
+        (CollisionDetector):
+        (CollisionDetector.prototype.handleNewFrame.get for):
+        (CollisionDetector.prototype.handleNewFrame):
+        * JetStream/cdjs/constants.js: Added.
+        * JetStream/cdjs/main.html: Added.
+        * JetStream/cdjs/main.js: Added.
+        * JetStream/cdjs/motion.js: Added.
+        (Motion):
+        (Motion.prototype.toString):
+        (Motion.prototype.delta):
+        (Motion.prototype.findIntersection):
+        * JetStream/cdjs/motion_test.js: Added.
+        (checkDoesIntersect):
+        (checkDoesNotIntersect):
+        (makeMotion):
+        * JetStream/cdjs/red_black_tree.js: Added.
+        (RedBlackTree):
+        (RedBlackTree.):
+        * JetStream/cdjs/red_black_tree_test.js: Added.
+        (test):
+        (test.):
+        * JetStream/cdjs/reduce_collision_set.js: Added.
+        (drawMotionOnVoxelMap):
+        (drawMotionOnVoxelMap.):
+        (.get reduceCollisionSet):
+        * JetStream/cdjs/reduce_collision_set_test.js: Added.
+        (makeMotion):
+        (keys):
+        (test):
+        * JetStream/cdjs/simulator.js: Added.
+        (Simulator):
+        (Simulator.prototype.simulate):
+        * JetStream/cdjs/util.js: Added.
+        (compareNumbers):
+        (averageAbovePercentile):
+        (currentTime):
+        (else.currentTime):
+        * JetStream/cdjs/vector_2d.js: Added.
+        (Vector2D):
+        (Vector2D.prototype.plus):
+        (Vector2D.prototype.minus):
+        (Vector2D.prototype.toString):
+        (Vector2D.prototype.compareTo):
+        * JetStream/cdjs/vector_3d.js: Added.
+        (Vector3D):
+        (Vector3D.prototype.plus):
+        (Vector3D.prototype.minus):
+        (Vector3D.prototype.dot):
+        (Vector3D.prototype.squaredMagnitude):
+        (Vector3D.prototype.magnitude):
+        (Vector3D.prototype.times):
+        (Vector3D.prototype.as2D):
+        (Vector3D.prototype.toString):
+        * JetStream/create.rb:
+        * JetStream/index-TEMPLATE.html:
+        * JetStream/sunspider/cordic.js: Removed.
+
</ins><span class="cx"> 2015-06-17  Javier Fernandez  &lt;jfernandez@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSS Grid Layout] We should add performance tests for stretching logic
</span></span></pre></div>
<a id="trunkPerformanceTestsJetStreamCDjsSetupjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/CDjsSetup.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/CDjsSetup.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/CDjsSetup.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+// Copyright (C) 2015 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. 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 APPLE INC. AND ITS 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 APPLE INC. OR ITS CONTRIBUTORS
+// 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 CDjsFiles = [
+    &quot;constants.js&quot;,
+    &quot;util.js&quot;,
+    &quot;red_black_tree.js&quot;,
+    &quot;call_sign.js&quot;,
+    &quot;vector_2d.js&quot;,
+    &quot;vector_3d.js&quot;,
+    &quot;motion.js&quot;,
+    &quot;reduce_collision_set.js&quot;,
+    &quot;simulator.js&quot;,
+    &quot;collision.js&quot;,
+    &quot;collision_detector.js&quot;,
+    &quot;benchmark.js&quot;
+];
+
+var code = &quot;&quot;;
+for (var i = 0; i &lt; CDjsFiles.length; ++i)
+    code += &quot;&lt;script src=\&quot;cdjs/&quot; + CDjsFiles[i] + &quot;\&quot;&gt;&lt;/script&gt;\n&quot;;
+code += &quot;&lt;script&gt;\n&quot;;
+code += &quot;console.log(\&quot;running...\&quot;);\n&quot;;
+code += &quot;var __result = benchmark();\n&quot;;
+code += &quot;console.log(\&quot;got result: \&quot; + __result);\n&quot;;
+code += &quot;top.JetStream.reportResult(__result);\n&quot;;
+code += &quot;&lt;/script&gt;&quot;;
+
+console.log(&quot;code = &quot; + code);
+
+JetStream.addPlan({
+    name: &quot;cdjs&quot;,
+    benchmarks: [{
+        name: &quot;cdjs&quot;,
+        category: &quot;Latency&quot;,
+        unit: &quot;ms&quot;
+    }],
+    code: code
+});
+
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamOctane2Setupjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/JetStream/Octane2Setup.js (185779 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/Octane2Setup.js        2015-06-19 23:45:35 UTC (rev 185779)
+++ trunk/PerformanceTests/JetStream/Octane2Setup.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-// Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+// Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
</ins><span class="cx"> //
</span><span class="cx"> // Redistribution and use in source and binary forms, with or without
</span><span class="cx"> // modification, are permitted provided that the following conditions
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx">     if (suite.latency) {
</span><span class="cx">         myBenchmarks.push({
</span><span class="cx">             name: suite.name + &quot;-latency&quot;,
</span><del>-            prefix: &quot;&amp;sigma; = &quot;,
</del><ins>+            unit: &quot;ms&quot;,
</ins><span class="cx">             category: &quot;Latency&quot;
</span><span class="cx">         });
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkPerformanceTestsJetStreamReferencejs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/JetStream/Reference.js (185779 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/Reference.js        2015-06-19 23:45:35 UTC (rev 185779)
+++ trunk/PerformanceTests/JetStream/Reference.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-// Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+// Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
</ins><span class="cx"> //
</span><span class="cx"> // Redistribution and use in source and binary forms, with or without
</span><span class="cx"> // modification, are permitted provided that the following conditions
</span><span class="lines">@@ -25,7 +25,6 @@
</span><span class="cx">     &quot;3d-cube&quot;: 7.3,
</span><span class="cx">     &quot;3d-raytrace&quot;: 8.05,
</span><span class="cx">     &quot;base64&quot;: 4.2,
</span><del>-    &quot;cordic&quot;: 3,
</del><span class="cx">     &quot;crypto-aes&quot;: 6.6,
</span><span class="cx">     &quot;crypto-md5&quot;: 3,
</span><span class="cx">     &quot;crypto-sha1&quot;: 2.05,
</span><span class="lines">@@ -65,5 +64,6 @@
</span><span class="cx">     &quot;zlib&quot;: 887.666666666666,
</span><span class="cx">     &quot;typescript&quot;: 1149.9999999999993,
</span><span class="cx">     &quot;lua&quot;: 29858,
</span><ins>+    &quot;cdjs&quot;: 14,
</ins><span class="cx">     &quot;geomean&quot;: 31.556451704472156,
</span><span class="cx"> });
</span></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsbenchmarkjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/benchmark.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/benchmark.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/benchmark.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,80 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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.
+
+function benchmark() {
+    var verbosity = 0;
+    var numAircraft = 1000;
+    var numFrames = 200;
+    var expectedCollisions = 14484;
+    var percentile = 95;
+
+    var simulator = new Simulator(numAircraft);
+    var detector = new CollisionDetector();
+    var lastTime = currentTime();
+    var results = [];
+    for (var i = 0; i &lt; numFrames; ++i) {
+        var time = i / 10;
+        
+        var collisions = detector.handleNewFrame(simulator.simulate(time));
+        
+        var before = lastTime;
+        var after = currentTime();
+        lastTime = after;
+        var result = {
+            time: after - before,
+            numCollisions: collisions.length
+        };
+        if (verbosity &gt;= 2)
+            result.collisions = collisions;
+        results.push(result);
+    }
+
+    if (verbosity &gt;= 1) {
+        for (var i = 0; i &lt; results.length; ++i) {
+            var string = &quot;Frame &quot; + i + &quot;: &quot; + results[i].time + &quot; ms.&quot;;
+            if (results[i].numCollisions)
+                string += &quot; (&quot; + results[i].numCollisions + &quot; collisions.)&quot;;
+            print(string);
+            if (verbosity &gt;= 2 &amp;&amp; results[i].collisions.length)
+                print(&quot;    Collisions: &quot; + results[i].collisions);
+        }
+    }
+
+    // Check results.
+    var actualCollisions = 0;
+    for (var i = 0; i &lt; results.length; ++i)
+        actualCollisions += results[i].numCollisions;
+    if (actualCollisions != expectedCollisions) {
+        throw new Error(&quot;Bad number of collisions: &quot; + actualCollisions + &quot; (expected &quot; +
+                        expectedCollisions + &quot;)&quot;);
+    }
+
+    // Find the worst 5% 
+    var times = [];
+    for (var i = 0; i &lt; results.length; ++i)
+        times.push(results[i].time);
+    
+    return averageAbovePercentile(times, percentile);
+}
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjscall_signjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/call_sign.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/call_sign.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/call_sign.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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.
+
+function CallSign(value) {
+    this._value = value;
+}
+
+CallSign.prototype.compareTo = function(other) {
+    return this._value.localeCompare(other._value);
+}
+
+CallSign.prototype.toString = function() {
+    return this._value;
+}
+
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjscollisionjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/collision.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/collision.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/collision.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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.
+
+function Collision(aircraft, position) {
+    this.aircraft = aircraft;
+    this.position = position;
+}
+
+Collision.prototype.toString = function() {
+    return &quot;Collision(&quot; + this.aircraft + &quot; at &quot; + this.position + &quot;)&quot;;
+};
+
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjscollision_detectorjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/collision_detector.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/collision_detector.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/collision_detector.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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.
+
+function CollisionDetector() {
+    this._state = new RedBlackTree();
+}
+
+CollisionDetector.prototype.handleNewFrame = function(frame) {
+    var motions = [];
+    var seen = new RedBlackTree();
+    
+    for (var i = 0; i &lt; frame.length; ++i) {
+        var aircraft = frame[i];
+        
+        var oldPosition = this._state.put(aircraft.callsign, aircraft.position);
+        var newPosition = aircraft.position;
+        seen.put(aircraft.callsign, true);
+        
+        if (!oldPosition) {
+            // Treat newly introduced aircraft as if they were stationary.
+            oldPosition = newPosition;
+        }
+        
+        motions.push(new Motion(aircraft.callsign, oldPosition, newPosition));
+    }
+    
+    // Remove aircraft that are no longer present.
+    var toRemove = [];
+    this._state.forEach(function(callsign, position) {
+        if (!seen.get(callsign))
+            toRemove.push(callsign);
+    });
+    for (var i = 0; i &lt; toRemove.length; ++i)
+        this._state.remove(toRemove[i]);
+    
+    var allReduced = reduceCollisionSet(motions);
+    var collisions = [];
+    for (var reductionIndex = 0; reductionIndex &lt; allReduced.length; ++reductionIndex) {
+        var reduced = allReduced[reductionIndex];
+        for (var i = 0; i &lt; reduced.length; ++i) {
+            var motion1 = reduced[i];
+            for (var j = i + 1; j &lt; reduced.length; ++j) {
+                var motion2 = reduced[j];
+                var collision = motion1.findIntersection(motion2);
+                if (collision)
+                    collisions.push(new Collision([motion1.callsign, motion2.callsign], collision));
+            }
+        }
+    }
+    
+    return collisions;
+};
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsconstantsjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/constants.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/constants.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/constants.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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 Constants = {};
+Constants.MIN_X = 0;
+Constants.MIN_Y = 0;
+Constants.MAX_X = 1000;
+Constants.MAX_Y = 1000;
+Constants.MIN_Z = 0;
+Constants.MAX_Z = 10;
+Constants.PROXIMITY_RADIUS = 1;
+Constants.GOOD_VOXEL_SIZE = Constants.PROXIMITY_RADIUS * 2;
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsmainhtml"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/main.html (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/main.html                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/main.html        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,58 @@
</span><ins>+&lt;!--
+ Copyright (c) 2001-2010, Purdue University. All rights reserved.
+ Copyright (C) 2015 Apple Inc. 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.
+  * Neither the name of the Purdue University nor the
+    names of its 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 &quot;AS IS&quot; 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.
+--&gt;
+
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;CDjs&lt;/title&gt;
+&lt;script src=&quot;constants.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;util.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;red_black_tree.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;call_sign.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;vector_2d.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;vector_3d.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;motion.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;reduce_collision_set.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;simulator.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;collision.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;collision_detector.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;benchmark.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+    function runTest() {
+        var result = benchmark();
+        document.getElementById(&quot;result-summary&quot;).innerHTML = &quot;Average worst case: &quot; + result;
+    }
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;h1&gt;CDjs&lt;/h1&gt;
+&lt;p&gt;
+  &lt;div id=&quot;result-summary&quot;&gt;&lt;/div&gt;
+  &lt;div&gt;&lt;a href=&quot;javascript:runTest()&quot;&gt;Start Test&lt;/a&gt;&lt;/div&gt;
+&lt;/p&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsmainjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/main.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/main.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/main.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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.
+
+load(&quot;constants.js&quot;);
+load(&quot;util.js&quot;);
+load(&quot;red_black_tree.js&quot;);
+load(&quot;call_sign.js&quot;);
+load(&quot;vector_2d.js&quot;);
+load(&quot;vector_3d.js&quot;);
+load(&quot;motion.js&quot;);
+load(&quot;reduce_collision_set.js&quot;);
+load(&quot;simulator.js&quot;);
+load(&quot;collision.js&quot;);
+load(&quot;collision_detector.js&quot;);
+load(&quot;benchmark.js&quot;);
+
+var result = benchmark();
+
+print(&quot;Average worst case: &quot; + result + &quot; ms.&quot;);
+
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsmotionjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/motion.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/motion.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/motion.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,136 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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.
+
+function Motion(callsign, posOne, posTwo) {
+    this.callsign = callsign;
+    this.posOne = posOne;
+    this.posTwo = posTwo;
+}
+
+Motion.prototype.toString = function() {
+    return &quot;Motion(&quot; + this.callsign + &quot; from &quot; + this.posOne + &quot; to &quot; + this.posTwo + &quot;)&quot;;
+};
+
+Motion.prototype.delta = function() {
+    return this.posTwo.minus(this.posOne);
+};
+
+Motion.prototype.findIntersection = function(other) {
+    var init1 = this.posOne;
+    var init2 = other.posOne;
+    var vec1 = this.delta();
+    var vec2 = other.delta();
+    var radius = Constants.PROXIMITY_RADIUS;
+    
+    // this test is not geometrical 3-d intersection test, it takes the fact that the aircraft move
+    // into account ; so it is more like a 4d test
+    // (it assumes that both of the aircraft have a constant speed over the tested interval)
+    
+    // we thus have two points, each of them moving on its line segment at constant speed ; we are looking
+    // for times when the distance between these two points is smaller than r 
+    
+    // vec1 is vector of aircraft 1
+    // vec2 is vector of aircraft 2
+    
+    // a = (V2 - V1)^T * (V2 - V1)
+    var a = vec2.minus(vec1).squaredMagnitude();
+    
+    if (a != 0) {
+        // we are first looking for instances of time when the planes are exactly r from each other
+        // at least one plane is moving ; if the planes are moving in parallel, they do not have constant speed
+
+        // if the planes are moving in parallel, then
+        //   if the faster starts behind the slower, we can have 2, 1, or 0 solutions
+        //   if the faster plane starts in front of the slower, we can have 0 or 1 solutions
+
+        // if the planes are not moving in parallel, then
+
+
+        // point P1 = I1 + vV1
+        // point P2 = I2 + vV2
+        //   - looking for v, such that dist(P1,P2) = || P1 - P2 || = r
+
+        // it follows that || P1 - P2 || = sqrt( &lt; P1-P2, P1-P2 &gt; )
+        //   0 = -r^2 + &lt; P1 - P2, P1 - P2 &gt;
+        //  from properties of dot product
+        //   0 = -r^2 + &lt;I1-I2,I1-I2&gt; + v * 2&lt;I1-I2, V1-V2&gt; + v^2 *&lt;V1-V2,V1-V2&gt;
+        //   so we calculate a, b, c - and solve the quadratic equation
+        //   0 = c + bv + av^2
+
+        // b = 2 * &lt;I1-I2, V1-V2&gt;
+
+        var b = 2 * init1.minus(init2).dot(vec1.minus(vec2));
+
+        // c = -r^2 + (I2 - I1)^T * (I2 - I1)
+        var c = -radius * radius + init2.minus(init1).squaredMagnitude();
+
+        var discr = b * b - 4 * a * c;
+        if (discr &lt; 0)
+            return null;
+
+        var v1 = (-b - Math.sqrt(discr)) / (2 * a);
+        var v2 = (-b + Math.sqrt(discr)) / (2 * a);
+
+        if (v1 &lt;= v2 &amp;&amp; ((v1 &lt;= 1 &amp;&amp; 1 &lt;= v2) ||
+                         (v1 &lt;= 0 &amp;&amp; 0 &lt;= v2) ||
+                         (0 &lt;= v1 &amp;&amp; v2 &lt;= 1))) {
+            // Pick a good &quot;time&quot; at which to report the collision.
+            var v;
+            if (v1 &lt;= 0) {
+                // The collision started before this frame. Report it at the start of the frame.
+                v = 0;
+            } else {
+                // The collision started during this frame. Report it at that moment.
+                v = v1;
+            }
+            
+            var result1 = init1.plus(vec1.times(v));
+            var result2 = init2.plus(vec2.times(v));
+            
+            var result = result1.plus(result2).times(0.5);
+            if (result.x &gt;= Constants.MIN_X &amp;&amp;
+                result.x &lt;= Constants.MAX_X &amp;&amp;
+                result.y &gt;= Constants.MIN_Y &amp;&amp;
+                result.y &lt;= Constants.MAX_Y &amp;&amp;
+                result.z &gt;= Constants.MIN_Z &amp;&amp;
+                result.z &lt;= Constants.MAX_Z)
+                return result;
+        }
+
+return null;
+    }
+    
+    // the planes have the same speeds and are moving in parallel (or they are not moving at all)
+    // they  thus have the same distance all the time ; we calculate it from the initial point
+    
+    // dist = || i2 - i1 || = sqrt(  ( i2 - i1 )^T * ( i2 - i1 ) )
+    
+    var dist = init2.minus(init1).magnitude();
+    if (dist &lt;= radius)
+        return init1.plus(init2).times(0.5);
+    
+    return null;
+};
+
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsmotion_testjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/motion_test.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/motion_test.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/motion_test.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,93 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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.
+
+load(&quot;constants.js&quot;);
+load(&quot;util.js&quot;);
+load(&quot;call_sign.js&quot;);
+load(&quot;vector_2d.js&quot;);
+load(&quot;vector_3d.js&quot;);
+load(&quot;motion.js&quot;);
+
+var epsilon = 0.000001;
+
+function checkDoesIntersect(motionOne, motionTwo, expected) {
+    print(motionOne + &quot; and &quot; + motionTwo + &quot;:&quot;);
+    var actual = motionOne.findIntersection(motionTwo);
+    if (!actual)
+        throw new Error(&quot;Was supposed to intersect at &quot; + expected + &quot; but didn't&quot;);
+    
+    var delta = actual.minus(expected).magnitude();
+    if (delta &gt; epsilon) {
+        throw new Error(&quot;Was supposed to intersect at &quot; + expected + &quot; but intersected at &quot; +
+                        actual + &quot;, which is &quot; + delta + &quot; away&quot;);
+    }
+    
+    print(&quot;    Intersected at &quot; + actual + &quot;, which is &quot; + delta + &quot; away from &quot; + expected + &quot;.&quot;);
+}
+
+function checkDoesNotIntersect(motionOne, motionTwo) {
+    print(motionOne + &quot; and &quot; + motionTwo + &quot;:&quot;);
+    var actual = motionOne.findIntersection(motionTwo);
+    if (actual)
+        throw new Error(&quot;Was not supposed to intersect but intersected at &quot; + actual);
+    
+    print(&quot;    No intersection, as expected.&quot;);
+}
+
+var makeMotion = (function() {
+    var counter = 0;
+    return function(x1, y1, z1, x2, y2, z2) {
+        return new Motion(new CallSign(&quot;foo&quot; + (++counter)),
+                          new Vector3D(x1, y1, z1),
+                          new Vector3D(x2, y2, z2));
+    }
+})();
+
+checkDoesNotIntersect(
+    makeMotion(0, 0, 0, 10, 0, 0),
+    makeMotion(0, 10, 0, 10, 10, 0));
+
+checkDoesNotIntersect(
+    makeMotion(0, 0, 0, 10, 0, 0),
+    makeMotion(0, 1 + epsilon, 0, 10, 1 + epsilon, 0));
+
+checkDoesIntersect(
+    makeMotion(0, 0, 0, 10, 0, 0),
+    makeMotion(0, 1, 0, 10, 1, 0),
+    new Vector3D(0, 0.5, 0));
+
+checkDoesIntersect(
+    makeMotion(0, 0, 0, 10, 0, 0),
+    makeMotion(0, 10, 0, 10, 0, 0),
+    new Vector3D(9, 0.5, 0));
+
+checkDoesIntersect(
+    makeMotion(0, 0, 0, 9.5, 0, 0),
+    makeMotion(0, 10, 0, 9.65, 0.35, 0),
+    new Vector3D(8.939830722446178, 0.49507224691354423, 0));
+
+// FIXME: Add more tests here. Sadly, the original Java code for this benchmark had an extensive
+// JUnit test suite for intersections, but this didn't get included in any of the releases and I no
+// longer have access to the original CVS repository (yes, CVS).
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsred_black_treejs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/red_black_tree.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/red_black_tree.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/red_black_tree.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,409 @@
</span><ins>+/*
+ * Copyright (C) 2010, 2011, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  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.
+ * 3.  Neither the name of Apple Inc. (&quot;Apple&quot;) nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; 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 APPLE OR ITS CONTRIBUTORS 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 RedBlackTree = (function(){
+    function compare(a, b) {
+        return a.compareTo(b);
+    }
+    
+    function treeMinimum(x) {
+        while (x.left)
+            x = x.left;
+        return x;
+    }
+    
+    function treeMaximum(x) {
+        while (x.right)
+            x = x.right;
+        return x;
+    }
+    
+    function Node(key, value) {
+        this.key = key;
+        this.value = value;
+        this.left = null;
+        this.right = null;
+        this.parent = null;
+        this.color = &quot;red&quot;;
+    }
+    
+    Node.prototype.successor = function() {
+        var x = this;
+        if (x.right)
+            return treeMinimum(x.right);
+        var y = x.parent;
+        while (y &amp;&amp; x == y.right) {
+            x = y;
+            y = y.parent;
+        }
+        return y;
+    };
+    
+    Node.prototype.predecessor = function() {
+        var x = this;
+        if (x.left)
+            return treeMaximum(x.left);
+        var y = x.parent;
+        while (y &amp;&amp; x == y.left) {
+            x = y;
+            y = y.parent;
+        }
+        return y;
+    };
+    
+    Node.prototype.toString = function() {
+        return this.key + &quot;=&gt;&quot; + this.value + &quot; (&quot; + this.color + &quot;)&quot;;
+    };
+    
+    function RedBlackTree() {
+        this._root = null;
+    }
+    
+    RedBlackTree.prototype.put = function(key, value) {
+        var insertionResult = this._treeInsert(key, value);
+        if (!insertionResult.isNewEntry)
+            return insertionResult.oldValue;
+        var x = insertionResult.newNode;
+        
+        while (x != this._root &amp;&amp; x.parent.color == &quot;red&quot;) {
+            if (x.parent == x.parent.parent.left) {
+                var y = x.parent.parent.right;
+                if (y &amp;&amp; y.color == &quot;red&quot;) {
+                    // Case 1
+                    x.parent.color = &quot;black&quot;;
+                    y.color = &quot;black&quot;;
+                    x.parent.parent.color = &quot;red&quot;;
+                    x = x.parent.parent;
+                } else {
+                    if (x == x.parent.right) {
+                        // Case 2
+                        x = x.parent;
+                        this._leftRotate(x);
+                    }
+                    // Case 3
+                    x.parent.color = &quot;black&quot;;
+                    x.parent.parent.color = &quot;red&quot;;
+                    this._rightRotate(x.parent.parent);
+                }
+            } else {
+                // Same as &quot;then&quot; clause with &quot;right&quot; and &quot;left&quot; exchanged.
+                var y = x.parent.parent.left;
+                if (y &amp;&amp; y.color == &quot;red&quot;) {
+                    // Case 1
+                    x.parent.color = &quot;black&quot;;
+                    y.color = &quot;black&quot;;
+                    x.parent.parent.color = &quot;red&quot;;
+                    x = x.parent.parent;
+                } else {
+                    if (x == x.parent.left) {
+                        // Case 2
+                        x = x.parent;
+                        this._rightRotate(x);
+                    }
+                    // Case 3
+                    x.parent.color = &quot;black&quot;;
+                    x.parent.parent.color = &quot;red&quot;;
+                    this._leftRotate(x.parent.parent);
+                }
+            }
+        }
+        
+        this._root.color = &quot;black&quot;;
+        return null;
+    };
+    
+    RedBlackTree.prototype.remove = function(key) {
+        var z = this._findNode(key);
+        if (!z)
+            return null;
+        
+        // Y is the node to be unlinked from the tree.
+        var y;
+        if (!z.left || !z.right)
+            y = z;
+        else
+            y = z.successor();
+
+        // Y is guaranteed to be non-null at this point.
+        var x;
+        if (y.left)
+            x = y.left;
+        else
+            x = y.right;
+        
+        // X is the child of y which might potentially replace y in the tree. X might be null at
+        // this point.
+        var xParent;
+        if (x) {
+            x.parent = y.parent;
+            xParent = x.parent;
+        } else
+            xParent = y.parent;
+        if (!y.parent)
+            this._root = x;
+        else {
+            if (y == y.parent.left)
+                y.parent.left = x;
+            else
+                y.parent.right = x;
+        }
+        
+        if (y != z) {
+            if (y.color == &quot;black&quot;)
+                this._removeFixup(x, xParent);
+            
+            y.parent = z.parent;
+            y.color = z.color;
+            y.left = z.left;
+            y.right = z.right;
+            
+            if (z.left)
+                z.left.parent = y;
+            if (z.right)
+                z.right.parent = y;
+            if (z.parent) {
+                if (z.parent.left == z)
+                    z.parent.left = y;
+                else
+                    z.parent.right = y;
+            } else
+                this._root = y;
+        } else if (y.color == &quot;black&quot;)
+            this._removeFixup(x, xParent);
+        
+        return z.value;
+    };
+    
+    RedBlackTree.prototype.get = function(key) {
+        var node = this._findNode(key);
+        if (!node)
+            return null;
+        return node.value;
+    };
+    
+    RedBlackTree.prototype.forEach = function(callback) {
+        if (!this._root)
+            return;
+        for (var current = treeMinimum(this._root); current; current = current.successor())
+            callback(current.key, current.value);
+    };
+    
+    RedBlackTree.prototype.asArray = function() {
+        var result = [];
+        this.forEach(function(key, value) {
+            result.push({key: key, value: value});
+        });
+        return result;
+    };
+    
+    RedBlackTree.prototype.toString = function() {
+        var result = &quot;[&quot;;
+        var first = true;
+        this.forEach(function(key, value) {
+            if (first)
+                first = false;
+            else
+                result += &quot;, &quot;;
+            result += key + &quot;=&gt;&quot; + value;
+        });
+        return result + &quot;]&quot;;
+    };
+    
+    RedBlackTree.prototype._findNode = function(key) {
+        for (var current = this._root; current;) {
+            var comparisonResult = compare(key, current.key);
+            if (!comparisonResult)
+                return current;
+            if (comparisonResult &lt; 0)
+                current = current.left;
+            else
+                current = current.right;
+        }
+        return null;
+    };
+    
+    RedBlackTree.prototype._treeInsert = function(key, value) {
+        var y = null;
+        var x = this._root;
+        while (x) {
+            y = x;
+            var comparisonResult = key.compareTo(x.key);
+            if (comparisonResult &lt; 0)
+                x = x.left;
+            else if (comparisonResult &gt; 0)
+                x = x.right;
+            else {
+                var oldValue = x.value;
+                x.value = value;
+                return {isNewEntry:false, oldValue:oldValue};
+            }
+        }
+        var z = new Node(key, value);
+        z.parent = y;
+        if (!y)
+            this._root = z;
+        else {
+            if (key.compareTo(y.key) &lt; 0)
+                y.left = z;
+            else
+                y.right = z;
+        }
+        return {isNewEntry:true, newNode:z};
+    };
+    
+    RedBlackTree.prototype._leftRotate = function(x) {
+        var y = x.right;
+        
+        // Turn y's left subtree into x's right subtree.
+        x.right = y.left;
+        if (y.left)
+            y.left.parent = x;
+        
+        // Link x's parent to y.
+        y.parent = x.parent;
+        if (!x.parent)
+            this._root = y;
+        else {
+            if (x == x.parent.left)
+                x.parent.left = y;
+            else
+                x.parent.right = y;
+        }
+        
+        // Put x on y's left.
+        y.left = x;
+        x.parent = y;
+        
+        return y;
+    };
+    
+    RedBlackTree.prototype._rightRotate = function(y) {
+        var x = y.left;
+        
+        // Turn x's right subtree into y's left subtree.
+        y.left = x.right;
+        if (x.right)
+            x.right.parent = y;
+        
+        // Link y's parent to x;
+        x.parent = y.parent;
+        if (!y.parent)
+            this._root = x;
+        else {
+            if (y == y.parent.left)
+                y.parent.left = x;
+            else
+                y.parent.right = x;
+        }
+        
+        x.right = y;
+        y.parent = x;
+        
+        return x;
+    };
+    
+    RedBlackTree.prototype._removeFixup = function(x, xParent) {
+        while (x != this._root &amp;&amp; (!x || x.color == &quot;black&quot;)) {
+            if (x == xParent.left) {
+                // Note: the text points out that w cannot be null. The reason is not obvious from
+                // simply looking at the code; it comes about from the properties of the red-black
+                // tree.
+                var w = xParent.right;
+                if (w.color == &quot;red&quot;) {
+                    // Case 1
+                    w.color = &quot;black&quot;;
+                    xParent.color = &quot;red&quot;;
+                    this._leftRotate(xParent);
+                    w = xParent.right;
+                }
+                if ((!w.left || w.left.color == &quot;black&quot;)
+                    &amp;&amp; (!w.right || w.right.color == &quot;black&quot;)) {
+                    // Case 2
+                    w.color = &quot;red&quot;;
+                    x = xParent;
+                    xParent = x.parent;
+                } else {
+                    if (!w.right || w.right.color == &quot;black&quot;) {
+                        // Case 3
+                        w.left.color = &quot;black&quot;;
+                        w.color = &quot;red&quot;;
+                        this._rightRotate(w);
+                        w = xParent.right;
+                    }
+                    // Case 4
+                    w.color = xParent.color;
+                    xParent.color = &quot;black&quot;;
+                    if (w.right)
+                        w.right.color = &quot;black&quot;;
+                    this._leftRotate(xParent);
+                    x = this._root;
+                    xParent = x.parent;
+                }
+            } else {
+                // Same as &quot;then&quot; clause with &quot;right&quot; and &quot;left&quot; exchanged.
+                
+                var w = xParent.left;
+                if (w.color == &quot;red&quot;) {
+                    // Case 1
+                    w.color = &quot;black&quot;;
+                    xParent.color = &quot;red&quot;;
+                    this._rightRotate(xParent);
+                    w = xParent.left;
+                }
+                if ((!w.right || w.right.color == &quot;black&quot;)
+                    &amp;&amp; (!w.left || w.left.color == &quot;black&quot;)) {
+                    // Case 2
+                    w.color = &quot;red&quot;;
+                    x = xParent;
+                    xParent = x.parent;
+                } else {
+                    if (!w.left || w.left.color == &quot;black&quot;) {
+                        // Case 3
+                        w.right.color = &quot;black&quot;;
+                        w.color = &quot;red&quot;;
+                        this._leftRotate(w);
+                        w = xParent.left;
+                    }
+                    // Case 4
+                    w.color = xParent.color;
+                    xParent.color = &quot;black&quot;;
+                    if (w.left)
+                        w.left.color = &quot;black&quot;;
+                    this._rightRotate(xParent);
+                    x = this._root;
+                    xParent = x.parent;
+                }
+            }
+        }
+        if (x)
+            x.color = &quot;black&quot;;
+    };
+    
+    return RedBlackTree;
+})();
+
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsred_black_tree_testjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/red_black_tree_test.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/red_black_tree_test.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/red_black_tree_test.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,154 @@
</span><ins>+/*
+ * Copyright (C) 2010, 2011, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  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.
+ * 3.  Neither the name of Apple Inc. (&quot;Apple&quot;) nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; 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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+load(&quot;red_black_tree.js&quot;);
+
+// The control string is a list of commands. Each command is two characters, with the first
+// identifying the operation and the second giving a key.
+var test = (function(){
+    function PairVector() {
+        this._vector = [];
+    }
+
+    PairVector.prototype.put = function(key, value) {
+        for (var i = 0; i &lt; this._vector.length; ++i) {
+            if (!this._vector[i].key.compareTo(key)) {
+                var result = this._vector[i].value;
+                this._vector[i].value = value;
+                return result;
+            }
+        }
+        this._vector.push({key: key, value: value});
+        return null;
+    };
+
+    PairVector.prototype.remove = function(key, value) {
+        for (var i = 0; i &lt; this._vector.length; ++i) {
+            if (!this._vector[i].key.compareTo(key)) {
+                var result = this._vector[i].value;
+                this._vector[i] = this._vector[this._vector.length - 1];
+                this._vector.pop();
+                return result;
+            }
+        }
+        return null;
+    };
+
+    PairVector.prototype.get = function(key, value) {
+        for (var i = 0; i &lt; this._vector.length; ++i) {
+            if (!this._vector[i].key.compareTo(key))
+                return this._vector[i].value;
+        }
+        return null;
+    };
+    
+    PairVector.prototype.toString = function() {
+        var copy = this._vector.concat();
+        copy.sort(function(a, b) {
+            return a.key.compareTo(b.key);
+        });
+        var result = &quot;[&quot;;
+        for (var i = 0; i &lt; copy.length; ++i) {
+            if (i)
+                result += &quot;, &quot;;
+            result += copy[i].key + &quot;=&gt;&quot; + copy[i].value;
+        }
+        return result + &quot;]&quot;;
+    };
+    
+    String.prototype.compareTo = String.prototype.localeCompare;
+
+    var counter = 0;
+    
+    return function(controlString) {
+        print(&quot;Running &quot; + JSON.stringify(controlString) + &quot;:&quot;);
+        var asVector = new PairVector();
+        var asTree = new RedBlackTree();
+        
+        function fail(when) {
+            throw new Error(
+                &quot;FAIL: &quot; + when + &quot;, tree = &quot; + asTree + &quot;, vector = &quot; + asVector);
+        }
+        
+        for (var index = 0; index &lt; controlString.length; index += 2) {
+            var command = controlString[index];
+            var key = controlString[index + 1];
+            var value = ++counter;
+            
+            switch (command) {
+            case &quot;+&quot;:
+                var oldVectorValue = asVector.put(key, value);
+                var oldTreeValue = asTree.put(key, value);
+                if (oldVectorValue !== oldTreeValue) {
+                    fail(&quot;Adding &quot; + key + &quot;=&gt;&quot; + value + &quot;, vector got &quot; +
+                         oldVectorValue + &quot; but tree got &quot; + oldTreeValue);
+                }
+                break;
+                
+            case &quot;*&quot;:
+                var oldVectorValue = asVector.get(key);
+                var oldTreeValue = asTree.get(key);
+                if (oldVectorValue !== oldTreeValue) {
+                    fail(&quot;Getting &quot; + key + &quot;, vector got &quot; +
+                         oldVectorValue + &quot; but tree got &quot; + oldTreeValue);
+                }
+                break;
+                
+            case &quot;!&quot;:
+                var oldVectorValue = asVector.remove(key);
+                var oldTreeValue = asTree.remove(key);
+                if (oldVectorValue !== oldTreeValue) {
+                    fail(&quot;Removing &quot; + key + &quot;, vector got &quot; +
+                         oldVectorValue + &quot; but tree got &quot; + oldTreeValue);
+                }
+                break;
+                
+            default:
+                throw Error(&quot;Bad command: &quot; + command);
+            }
+        }
+        
+        if (&quot;&quot; + asVector != &quot;&quot; + asTree)
+            fail(&quot;Bad result at end&quot;);
+        
+        print(&quot;    Success, tree is: &quot; + asTree);
+    };
+})();
+
+test(&quot;&quot;);
+test(&quot;+a&quot;);
+test(&quot;*x!z&quot;);
+test(&quot;+a*x!z&quot;);
+test(&quot;+a*a!a&quot;);
+test(&quot;+a+b&quot;);
+test(&quot;+a+b+c&quot;);
+test(&quot;+a+b+c+d&quot;);
+test(&quot;+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d&quot;);
+test(&quot;+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+x+y+z&quot;);
+test(&quot;+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+x+y+z*a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z!a!b!c!d!e!f!g!h!i!j!k!l!m!n!o!p!q!r!s!t!u!v!w!x!y!z&quot;);
+
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsreduce_collision_setjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/reduce_collision_set.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/reduce_collision_set.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/reduce_collision_set.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,148 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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 drawMotionOnVoxelMap = (function() {
+    var voxelSize = Constants.GOOD_VOXEL_SIZE;
+    var horizontal = new Vector2D(voxelSize, 0);
+    var vertical = new Vector2D(0, voxelSize);
+    
+    function voxelHash(position) {
+        var xDiv = (position.x / voxelSize) | 0;
+        var yDiv = (position.y / voxelSize) | 0;
+        
+        var result = new Vector2D();
+        result.x = voxelSize * xDiv;
+        result.y = voxelSize * yDiv;
+        
+        if (position.x &lt; 0)
+            result.x -= voxelSize;
+        if (position.y &lt; 0)
+            result.y -= voxelSize;
+        
+        return result;
+    }
+    
+    return function(voxelMap, motion) {
+        var seen = new RedBlackTree();
+        
+        function putIntoMap(voxel) {
+            var array = voxelMap.get(voxel);
+            if (!array)
+                voxelMap.put(voxel, array = []);
+            array.push(motion);
+        }
+        
+        function isInVoxel(voxel) {
+            if (voxel.x &gt; Constants.MAX_X ||
+                voxel.x &lt; Constants.MIN_X ||
+                voxel.y &gt; Constants.MAX_Y ||
+                voxel.y &lt; Constants.MIN_Y)
+                return false;
+            
+            var init = motion.posOne;
+            var fin = motion.posTwo;
+            
+            var v_s = voxelSize;
+            var r = Constants.PROXIMITY_RADIUS / 2;
+            
+            var v_x = voxel.x;
+            var x0 = init.x;
+            var xv = fin.x - init.x;
+            
+            var v_y = voxel.y;
+            var y0 = init.y;
+            var yv = fin.y - init.y;
+            
+            var low_x, high_x;
+            low_x = (v_x - r - x0) / xv;
+            high_x = (v_x + v_s + r - x0) / xv;
+            
+            if (xv &lt; 0) {
+                var tmp = low_x;
+                low_x = high_x;
+                high_x = tmp;
+            }
+            
+            var low_y, high_y;
+            low_y = (v_y - r - y0) / yv;
+            high_y = (v_y + v_s + r - y0) / yv;
+            
+            if (yv &lt; 0) {
+                var tmp = low_y;
+                low_y = high_y;
+                high_y = tmp;
+            }
+            
+            if (false) {
+                print(&quot;v_x = &quot; + v_x + &quot;, x0 = &quot; + x0 + &quot;, xv = &quot; + xv + &quot;, v_y = &quot; + v_y + &quot;, y0 = &quot; + y0 + &quot;, yv = &quot; + yv + &quot;, low_x = &quot; + low_x + &quot;, low_y = &quot; + low_y + &quot;, high_x = &quot; + high_x + &quot;, high_y = &quot; + high_y);
+            }
+            
+            return (((xv == 0 &amp;&amp; v_x &lt;= x0 + r &amp;&amp; x0 - r &lt;= v_x + v_s) /* no motion in x */ || 
+                     ((low_x &lt;= 1 &amp;&amp; 1 &lt;= high_x) || (low_x &lt;= 0 &amp;&amp; 0 &lt;= high_x) ||
+                      (0 &lt;= low_x &amp;&amp; high_x &lt;= 1))) &amp;&amp; 
+                    ((yv == 0 &amp;&amp; v_y &lt;= y0 + r &amp;&amp; y0 - r &lt;= v_y + v_s) /* no motion in y */ || 
+                     ((low_y &lt;= 1 &amp;&amp; 1 &lt;= high_y) || (low_y &lt;= 0 &amp;&amp; 0 &lt;= high_y) ||
+                      (0 &lt;= low_y &amp;&amp; high_y &lt;= 1))) &amp;&amp; 
+                    (xv == 0 || yv == 0 || /* no motion in x or y or both */
+                     (low_y &lt;= high_x &amp;&amp; high_x &lt;= high_y) ||
+                     (low_y &lt;= low_x &amp;&amp; low_x &lt;= high_y) ||
+                     (low_x &lt;= low_y &amp;&amp; high_y &lt;= high_x)));
+        }
+        
+        function recurse(nextVoxel) {
+            if (!isInVoxel(nextVoxel, motion))
+                return;
+            if (seen.put(nextVoxel, true))
+                return;
+            
+            putIntoMap(nextVoxel);
+            
+            recurse(nextVoxel.minus(horizontal));
+            recurse(nextVoxel.plus(horizontal));
+            recurse(nextVoxel.minus(vertical));
+            recurse(nextVoxel.plus(vertical));
+            recurse(nextVoxel.minus(horizontal).minus(vertical));
+            recurse(nextVoxel.minus(horizontal).plus(vertical));
+            recurse(nextVoxel.plus(horizontal).minus(vertical));
+            recurse(nextVoxel.plus(horizontal).plus(vertical));
+        }
+        
+        recurse(voxelHash(motion.posOne));
+    };
+})();
+
+function reduceCollisionSet(motions) {
+    var voxelMap = new RedBlackTree();
+    for (var i = 0; i &lt; motions.length; ++i)
+        drawMotionOnVoxelMap(voxelMap, motions[i]);
+        
+    var result = [];
+    voxelMap.forEach(function(key, value) {
+        if (value.length &gt; 1)
+            result.push(value);
+    });
+    return result;
+}
+
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsreduce_collision_set_testjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/reduce_collision_set_test.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/reduce_collision_set_test.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/reduce_collision_set_test.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,82 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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.
+
+load(&quot;constants.js&quot;);
+load(&quot;util.js&quot;);
+load(&quot;red_black_tree.js&quot;);
+load(&quot;call_sign.js&quot;);
+load(&quot;vector_2d.js&quot;);
+load(&quot;vector_3d.js&quot;);
+load(&quot;motion.js&quot;);
+load(&quot;reduce_collision_set.js&quot;);
+
+var makeMotion = (function() {
+    var counter = 0;
+    return function(x1, y1, z1, x2, y2, z2) {
+        return new Motion(new CallSign(&quot;foo&quot; + (++counter)),
+                          new Vector3D(x1, y1, z1),
+                          new Vector3D(x2, y2, z2));
+    }
+})();
+
+function drawMotion(motion) {
+    var voxelMap = new RedBlackTree();
+    drawMotionOnVoxelMap(voxelMap, motion);
+    return voxelMap;
+}
+
+function keys(voxelMap) {
+    var result = &quot;[&quot;;
+    var first = true;
+    voxelMap.forEach(function(key, value) {
+        if (first)
+            first = false;
+        else
+            result += &quot;, &quot;;
+        result += key;
+    });
+    return result + &quot;]&quot;;
+}
+
+function test(x1, y1, z1, x2, y2, z2, expected) {
+    var motion = makeMotion(x1, y1, z1, x2, y2, z2);
+    print(motion + &quot;:&quot;);
+    var actual = keys(drawMotion(motion));
+    if (expected != actual)
+        throw new Error(&quot;Wrong voxel map: &quot; + actual);
+    print(&quot;    Got: &quot; + actual);
+}
+
+test(0, 0, 0, 1, 1, 1, &quot;[[0, 0]]&quot;);
+test(0, 0, 0, 2, 2, 2, &quot;[[0, 0], [0, 2], [2, 0], [2, 2]]&quot;);
+test(0, 0, 0, 4, 4, 4, &quot;[[0, 0], [0, 2], [2, 0], [2, 2], [2, 4], [4, 2], [4, 4]]&quot;);
+test(0, 0, 0, 10, 0, 0, &quot;[[0, 0], [2, 0], [4, 0], [6, 0], [8, 0], [10, 0]]&quot;);
+test(2, 0, 0, 0, 2, 2, &quot;[[0, 0], [0, 2], [2, 0]]&quot;);
+test(0, 2, 0, 2, 0, 2, &quot;[[0, 0], [0, 2], [2, 0]]&quot;);
+test(2, 2, 0, 0, 0, 2, &quot;[[0, 0], [0, 2], [2, 0], [2, 2]]&quot;);
+test(0, 0, 0, 2, 0, 0, &quot;[[0, 0], [2, 0]]&quot;);
+test(0, 0, 0, 0, 2, 0, &quot;[[0, 0], [0, 2]]&quot;);
+test(2, 0, 0, 0, 0, 0, &quot;[[0, 0], [2, 0]]&quot;);
+test(0, 2, 0, 0, 0, 0, &quot;[[0, 0], [0, 2]]&quot;);
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjssimulatorjs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/simulator.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/simulator.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/simulator.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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.
+
+function Simulator(numAircraft) {
+    this._aircraft = [];
+    for (var i = 0; i &lt; numAircraft; ++i)
+        this._aircraft.push(new CallSign(&quot;foo&quot; + i));
+}
+
+Simulator.prototype.simulate = function(time) {
+    var frame = [];
+    for (var i = 0; i &lt; this._aircraft.length; i += 2) {
+        frame.push({
+            callsign: this._aircraft[i],
+            position: new Vector3D(time, Math.cos(time) * 2 + i * 3, 10)
+        });
+        frame.push({
+            callsign: this._aircraft[i + 1],
+            position: new Vector3D(time, Math.sin(time) * 2 + i * 3, 10)
+        });
+    }
+    return frame;
+};
+
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsutiljs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/util.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/util.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/util.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,82 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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.
+
+function compareNumbers(a, b) {
+    if (a == b)
+        return 0;
+    if (a &lt; b)
+        return -1;
+    if (a &gt; b)
+        return 1;
+    
+    // We say that NaN is smaller than non-NaN.
+    if (a == a)
+        return 1;
+    return -1;
+}
+
+function averageAbovePercentile(numbers, percentile) {
+    // Don't change the original array.
+    numbers = numbers.slice();
+    
+    // Sort in ascending order.
+    numbers.sort(function(a, b) { return a - b; });
+    
+    // Now the elements we want are at the end. Keep removing them until the array size shrinks too much.
+    // Examples assuming percentile = 99:
+    //
+    // - numbers.length starts at 100: we will remove just the worst entry and then not remove anymore,
+    //   since then numbers.length / originalLength = 0.99.
+    //
+    // - numbers.length starts at 1000: we will remove the ten worst.
+    //
+    // - numbers.length starts at 10: we will remove just the worst.
+    var numbersWeWant = [];
+    var originalLength = numbers.length;
+    while (numbers.length / originalLength &gt; percentile / 100)
+        numbersWeWant.push(numbers.pop());
+    
+    var sum = 0;
+    for (var i = 0; i &lt; numbersWeWant.length; ++i)
+        sum += numbersWeWant[i];
+    
+    var result = sum / numbersWeWant.length;
+    
+    // Do a sanity check.
+    if (numbers.length &amp;&amp; result &lt; numbers[numbers.length - 1]) {
+        throw &quot;Sanity check fail: the worst case result is &quot; + result +
+            &quot; but we didn't take into account &quot; + numbers;
+    }
+    
+    return result;
+}
+
+var currentTime;
+if (this.performance &amp;&amp; performance.now)
+    currentTime = function() { return performance.now() };
+else if (preciseTime)
+    currentTime = function() { return preciseTime() * 1000; };
+else
+    currentTime = function() { return 0 + new Date(); };
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsvector_2djs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/vector_2d.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/vector_2d.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/vector_2d.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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.
+
+function Vector2D(x, y) {
+    this.x = x;
+    this.y = y;
+}
+
+Vector2D.prototype.plus = function(other) {
+    return new Vector2D(this.x + other.x,
+                        this.y + other.y);
+};
+
+Vector2D.prototype.minus = function(other) {
+    return new Vector2D(this.x - other.x,
+                        this.y - other.y);
+};
+
+Vector2D.prototype.toString = function() {
+    return &quot;[&quot; + this.x + &quot;, &quot; + this.y + &quot;]&quot;;
+};
+
+Vector2D.prototype.compareTo = function(other) {
+    var result = compareNumbers(this.x, other.x);
+    if (result)
+        return result;
+    return compareNumbers(this.y, other.y);
+};
+
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcdjsvector_3djs"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/JetStream/cdjs/vector_3d.js (0 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/cdjs/vector_3d.js                                (rev 0)
+++ trunk/PerformanceTests/JetStream/cdjs/vector_3d.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -0,0 +1,70 @@
</span><ins>+// Copyright (c) 2001-2010, Purdue University. All rights reserved.
+// Copyright (C) 2015 Apple Inc. 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.
+//  * Neither the name of the Purdue University nor the
+//    names of its 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 &quot;AS IS&quot; 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.
+
+function Vector3D(x, y, z) {
+    this.x = x;
+    this.y = y;
+    this.z = z;
+}
+
+Vector3D.prototype.plus = function(other) {
+    return new Vector3D(this.x + other.x,
+                        this.y + other.y,
+                        this.z + other.z);
+};
+
+Vector3D.prototype.minus = function(other) {
+    return new Vector3D(this.x - other.x,
+                        this.y - other.y,
+                        this.z - other.z);
+};
+
+Vector3D.prototype.dot = function(other) {
+    return this.x * other.x + this.y * other.y + this.z * other.z;
+};
+
+Vector3D.prototype.squaredMagnitude = function() {
+    return this.dot(this);
+};
+
+Vector3D.prototype.magnitude = function() {
+    return Math.sqrt(this.squaredMagnitude());
+};
+
+Vector3D.prototype.times = function(amount) {
+    return new Vector3D(this.x * amount,
+                        this.y * amount,
+                        this.z * amount);
+};
+
+Vector3D.prototype.as2D = function() {
+    return new Vector2D(this.x, this.y);
+};
+
+Vector3D.prototype.toString = function() {
+    return &quot;[&quot; + this.x + &quot;, &quot; + this.y + &quot;, &quot; + this.z + &quot;]&quot;;
+};
+
+
</ins></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcreaterb"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/JetStream/create.rb (185779 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/create.rb        2015-06-19 23:45:35 UTC (rev 185779)
+++ trunk/PerformanceTests/JetStream/create.rb        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -26,7 +26,7 @@
</span><span class="cx"> require &quot;pathname&quot;
</span><span class="cx"> require &quot;shellwords&quot;
</span><span class="cx"> 
</span><del>-VERSION = &quot;1.1-alpha1&quot;
</del><ins>+VERSION = &quot;1.1-alpha2&quot;
</ins><span class="cx"> DIRECTORY_NAME = &quot;JetStream-#{VERSION}&quot;
</span><span class="cx"> 
</span><span class="cx"> raise unless system(&quot;rm -rf &quot; + DIRECTORY_NAME)
</span><span class="lines">@@ -34,7 +34,7 @@
</span><span class="cx"> raise unless system(&quot;mkdir -p #{DIRECTORY_NAME}/sunspider&quot;)
</span><span class="cx"> raise unless system(&quot;mkdir -p #{DIRECTORY_NAME}/sources&quot;)
</span><span class="cx"> raise unless system(&quot;cp sunspider/*.js #{DIRECTORY_NAME}/sunspider&quot;)
</span><del>-raise unless system(&quot;cp -r JetStream.css JetStreamDriver.js LLVM-test-suite-LICENSE.txt simple Octane2 Octane2Setup.js SimpleSetup.js SunSpiderSetup.js Octane OctaneSetup.js Reference.js TestingSetup.js JetStream-Logo.png JetStream-Logo@2x.png Swoosh.png Swoosh@2x.png &quot; + DIRECTORY_NAME)
</del><ins>+raise unless system(&quot;cp -r JetStream.css JetStreamDriver.js LLVM-test-suite-LICENSE.txt simple Octane2 Octane2Setup.js SimpleSetup.js SunSpiderSetup.js Octane OctaneSetup.js CDjsSetup.js cdjs Reference.js TestingSetup.js JetStream-Logo.png JetStream-Logo@2x.png Swoosh.png Swoosh@2x.png &quot; + DIRECTORY_NAME)
</ins><span class="cx"> 
</span><span class="cx"> def detemplatize(basename)
</span><span class="cx">     File.open(DIRECTORY_NAME + &quot;/#{basename}.html&quot;, &quot;w&quot;) {
</span><span class="lines">@@ -116,6 +116,7 @@
</span><span class="cx"> transferSource(&quot;box2d&quot;, &quot;Octane2/box2d.js&quot;)
</span><span class="cx"> transferSource(&quot;zlib&quot;, &quot;Octane2/zlib.js&quot;, &quot;Octane2/zlib-data.js&quot;)
</span><span class="cx"> transferSource(&quot;typescript&quot;, &quot;Octane2/typescript.js&quot;, &quot;Octane2/typescript-compiler.js&quot;, &quot;Octane2/typescript-input.js&quot;)
</span><ins>+transferSource(&quot;cdjs&quot;, &quot;cdjs/constants.js&quot;, &quot;cdjs/util.js&quot;, &quot;cdjs/red_black_tree.js&quot;, &quot;cdjs/call_sign.js&quot;, &quot;cdjs/vector_2d.js&quot;, &quot;cdjs/vector_3d.js&quot;, &quot;cdjs/motion.js&quot;, &quot;cdjs/reduce_collision_set.js&quot;, &quot;cdjs/simulator.js&quot;, &quot;cdjs/collision.js&quot;, &quot;cdjs/collision_detector.js&quot;, &quot;cdjs/benchmark.js&quot;)
</ins><span class="cx"> 
</span><span class="cx"> puts &quot;You can now run JetStream by navigating to file://&quot; + (Pathname.new(DIRECTORY_NAME) + &quot;index.html&quot;).realpath.to_s
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkPerformanceTestsJetStreamindexTEMPLATEhtml"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/JetStream/index-TEMPLATE.html (185779 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/index-TEMPLATE.html        2015-06-19 23:45:35 UTC (rev 185779)
+++ trunk/PerformanceTests/JetStream/index-TEMPLATE.html        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -48,6 +48,7 @@
</span><span class="cx">     &lt;script src=&quot;SimpleSetup.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;OctaneSetup.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Octane2Setup.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;CDjsSetup.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Reference.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> &lt;/head&gt;
</span><span class="cx"> &lt;body onload=&quot;initialize()&quot;&gt;
</span></span></pre></div>
<a id="trunkPerformanceTestsJetStreamsunspidercordicjs"></a>
<div class="delfile"><h4>Deleted: trunk/PerformanceTests/JetStream/sunspider/cordic.js (185779 => 185780)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/sunspider/cordic.js        2015-06-19 23:45:35 UTC (rev 185779)
+++ trunk/PerformanceTests/JetStream/sunspider/cordic.js        2015-06-19 23:49:38 UTC (rev 185780)
</span><span class="lines">@@ -1,106 +0,0 @@
</span><del>-/*
- * Copyright (C) Rich Moore.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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 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 APPLE INC. OR
- * CONTRIBUTORS 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. 
- */
-
-/////. Start CORDIC
-
-var AG_CONST = 0.6072529350;
-
-function FIXED(X)
-{
-  return X * 65536.0;
-}
-
-function FLOAT(X)
-{
-  return X / 65536.0;
-}
-
-function DEG2RAD(X)
-{
-  return 0.017453 * (X);
-}
-
-var Angles = [
-  FIXED(45.0), FIXED(26.565), FIXED(14.0362), FIXED(7.12502),
-  FIXED(3.57633), FIXED(1.78991), FIXED(0.895174), FIXED(0.447614),
-  FIXED(0.223811), FIXED(0.111906), FIXED(0.055953),
-  FIXED(0.027977) 
-              ];
-
-var Target = 28.027;
-
-function cordicsincos(Target) {
-    var X;
-    var Y;
-    var TargetAngle;
-    var CurrAngle;
-    var Step;

-    X = FIXED(AG_CONST);         /* AG_CONST * cos(0) */
-    Y = 0;                       /* AG_CONST * sin(0) */
-
-    TargetAngle = FIXED(Target);
-    CurrAngle = 0;
-    for (Step = 0; Step &lt; 12; Step++) {
-        var NewX;
-        if (TargetAngle &gt; CurrAngle) {
-            NewX = X - (Y &gt;&gt; Step);
-            Y = (X &gt;&gt; Step) + Y;
-            X = NewX;
-            CurrAngle += Angles[Step];
-        } else {
-            NewX = X + (Y &gt;&gt; Step);
-            Y = -(X &gt;&gt; Step) + Y;
-            X = NewX;
-            CurrAngle -= Angles[Step];
-        }
-    }
-
-    return FLOAT(X) * FLOAT(Y);
-}
-
-///// End CORDIC
-
-var total = 0;
-
-function cordic( runs ) {
-  var start = new Date();
-
-  for ( var i = 0 ; i &lt; runs ; i++ ) {
-      total += cordicsincos(Target);
-  }
-
-  var end = new Date();
-
-  return end.getTime() - start.getTime();
-}
-
-cordic(25000);
-
-var expected = 10362.570468755888;
-
-if (total != expected)
-    throw &quot;ERROR: bad result: expected &quot; + expected + &quot; but got &quot; + total;
-
</del></span></pre>
</div>
</div>

</body>
</html>