77136354574234b28d09d4bd96e69f5c4af27ecb
[WebKit-https.git] / Websites / webkit.org / perf / sunspider-1.0.2 / sunspider-1.0.2 / sunspider-test-contents.js
1 var testContents = [ "<!DOCTYPE html>\n\
2 <head>\n\
3 \n\
4 <meta charset=utf8>\n\
5 \n\
6 <!--\n\
7  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
8 \n\
9  Redistribution and use in source and binary forms, with or without\n\
10  modification, are permitted provided that the following conditions\n\
11  are met:\n\
12  1. Redistributions of source code must retain the above copyright\n\
13     notice, this list of conditions and the following disclaimer.\n\
14  2. Redistributions in binary form must reproduce the above copyright\n\
15     notice, this list of conditions and the following disclaimer in the\n\
16     documentation and/or other materials provided with the distribution.\n\
17 \n\
18  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
19  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
20  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
21  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
22  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
23  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
24  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
25  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
26  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
27  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
28  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
29 -->\n\
30 \n\
31 <title>SunSpider 3d-cube</title>\n\
32 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
33 <style>\n\
34 #countdown {\n\
35     font-size: 128px; \n\
36     text-align: center;\n\
37 }\n\
38 </style>\n\
39 </head>\n\
40 \n\
41 <body>\n\
42 <h3 id=\"countdown\"></h3>\n\
43 <script>\n\
44 if (window.parent) {\n\
45     document.getElementById(\"countdown\").innerHTML =\n\
46         window.parent.currentRepeat < 0\n\
47             ? \"warmup\"\n\
48             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
49 }\n\
50 \n\
51 function record(time) {\n\
52     if (window.parent)\n\
53         parent.recordResult(time);\n\
54 }\n\
55 \n\
56 window.onerror = function(e) {\n\
57     console.log(\"3d-cube failed with error: \" + e);\n\
58     record(0 / 0);\n\
59 }\n\
60 \n\
61 var _sunSpiderStartDate = new Date();\n\
62 \n\
63 // 3D Cube Rotation\n\
64 // http://www.speich.net/computer/moztesting/3d.htm\n\
65 // Created by Simon Speich\n\
66 \n\
67 var Q = new Array();\n\
68 var MTrans = new Array();  // transformation matrix\n\
69 var MQube = new Array();  // position information of qube\n\
70 var I = new Array();      // entity matrix\n\
71 var Origin = new Object();\n\
72 var Testing = new Object();\n\
73 var LoopTimer;\n\
74 \n\
75 var validation = {\n\
76  20: 2889.0000000000045,\n\
77  40: 2889.0000000000055,\n\
78  80: 2889.000000000005,\n\
79  160: 2889.0000000000055\n\
80 };\n\
81 \n\
82 var DisplArea = new Object();\n\
83 DisplArea.Width = 300;\n\
84 DisplArea.Height = 300;\n\
85 \n\
86 function DrawLine(From, To) {\n\
87   var x1 = From.V[0];\n\
88   var x2 = To.V[0];\n\
89   var y1 = From.V[1];\n\
90   var y2 = To.V[1];\n\
91   var dx = Math.abs(x2 - x1);\n\
92   var dy = Math.abs(y2 - y1);\n\
93   var x = x1;\n\
94   var y = y1;\n\
95   var IncX1, IncY1;\n\
96   var IncX2, IncY2;  \n\
97   var Den;\n\
98   var Num;\n\
99   var NumAdd;\n\
100   var NumPix;\n\
101 \n\
102   if (x2 >= x1) {  IncX1 = 1; IncX2 = 1;  }\n\
103   else { IncX1 = -1; IncX2 = -1; }\n\
104   if (y2 >= y1)  {  IncY1 = 1; IncY2 = 1; }\n\
105   else { IncY1 = -1; IncY2 = -1; }\n\
106   if (dx >= dy) {\n\
107     IncX1 = 0;\n\
108     IncY2 = 0;\n\
109     Den = dx;\n\
110     Num = dx / 2;\n\
111     NumAdd = dy;\n\
112     NumPix = dx;\n\
113   }\n\
114   else {\n\
115     IncX2 = 0;\n\
116     IncY1 = 0;\n\
117     Den = dy;\n\
118     Num = dy / 2;\n\
119     NumAdd = dx;\n\
120     NumPix = dy;\n\
121   }\n\
122 \n\
123   NumPix = Math.round(Q.LastPx + NumPix);\n\
124 \n\
125   var i = Q.LastPx;\n\
126   for (; i < NumPix; i++) {\n\
127     Num += NumAdd;\n\
128     if (Num >= Den) {\n\
129       Num -= Den;\n\
130       x += IncX1;\n\
131       y += IncY1;\n\
132     }\n\
133     x += IncX2;\n\
134     y += IncY2;\n\
135   }\n\
136   Q.LastPx = NumPix;\n\
137 }\n\
138 \n\
139 function CalcCross(V0, V1) {\n\
140   var Cross = new Array();\n\
141   Cross[0] = V0[1]*V1[2] - V0[2]*V1[1];\n\
142   Cross[1] = V0[2]*V1[0] - V0[0]*V1[2];\n\
143   Cross[2] = V0[0]*V1[1] - V0[1]*V1[0];\n\
144   return Cross;\n\
145 }\n\
146 \n\
147 function CalcNormal(V0, V1, V2) {\n\
148   var A = new Array();   var B = new Array(); \n\
149   for (var i = 0; i < 3; i++) {\n\
150     A[i] = V0[i] - V1[i];\n\
151     B[i] = V2[i] - V1[i];\n\
152   }\n\
153   A = CalcCross(A, B);\n\
154   var Length = Math.sqrt(A[0]*A[0] + A[1]*A[1] + A[2]*A[2]); \n\
155   for (var i = 0; i < 3; i++) A[i] = A[i] / Length;\n\
156   A[3] = 1;\n\
157   return A;\n\
158 }\n\
159 \n\
160 function CreateP(X,Y,Z) {\n\
161   this.V = [X,Y,Z,1];\n\
162 }\n\
163 \n\
164 // multiplies two matrices\n\
165 function MMulti(M1, M2) {\n\
166   var M = [[],[],[],[]];\n\
167   var i = 0;\n\
168   var j = 0;\n\
169   for (; i < 4; i++) {\n\
170     j = 0;\n\
171     for (; j < 4; j++) M[i][j] = M1[i][0] * M2[0][j] + M1[i][1] * M2[1][j] + M1[i][2] * M2[2][j] + M1[i][3] * M2[3][j];\n\
172   }\n\
173   return M;\n\
174 }\n\
175 \n\
176 //multiplies matrix with vector\n\
177 function VMulti(M, V) {\n\
178   var Vect = new Array();\n\
179   var i = 0;\n\
180   for (;i < 4; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2] + M[i][3] * V[3];\n\
181   return Vect;\n\
182 }\n\
183 \n\
184 function VMulti2(M, V) {\n\
185   var Vect = new Array();\n\
186   var i = 0;\n\
187   for (;i < 3; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2];\n\
188   return Vect;\n\
189 }\n\
190 \n\
191 // add to matrices\n\
192 function MAdd(M1, M2) {\n\
193   var M = [[],[],[],[]];\n\
194   var i = 0;\n\
195   var j = 0;\n\
196   for (; i < 4; i++) {\n\
197     j = 0;\n\
198     for (; j < 4; j++) M[i][j] = M1[i][j] + M2[i][j];\n\
199   }\n\
200   return M;\n\
201 }\n\
202 \n\
203 function Translate(M, Dx, Dy, Dz) {\n\
204   var T = [\n\
205   [1,0,0,Dx],\n\
206   [0,1,0,Dy],\n\
207   [0,0,1,Dz],\n\
208   [0,0,0,1]\n\
209   ];\n\
210   return MMulti(T, M);\n\
211 }\n\
212 \n\
213 function RotateX(M, Phi) {\n\
214   var a = Phi;\n\
215   a *= Math.PI / 180;\n\
216   var Cos = Math.cos(a);\n\
217   var Sin = Math.sin(a);\n\
218   var R = [\n\
219   [1,0,0,0],\n\
220   [0,Cos,-Sin,0],\n\
221   [0,Sin,Cos,0],\n\
222   [0,0,0,1]\n\
223   ];\n\
224   return MMulti(R, M);\n\
225 }\n\
226 \n\
227 function RotateY(M, Phi) {\n\
228   var a = Phi;\n\
229   a *= Math.PI / 180;\n\
230   var Cos = Math.cos(a);\n\
231   var Sin = Math.sin(a);\n\
232   var R = [\n\
233   [Cos,0,Sin,0],\n\
234   [0,1,0,0],\n\
235   [-Sin,0,Cos,0],\n\
236   [0,0,0,1]\n\
237   ];\n\
238   return MMulti(R, M);\n\
239 }\n\
240 \n\
241 function RotateZ(M, Phi) {\n\
242   var a = Phi;\n\
243   a *= Math.PI / 180;\n\
244   var Cos = Math.cos(a);\n\
245   var Sin = Math.sin(a);\n\
246   var R = [\n\
247   [Cos,-Sin,0,0],\n\
248   [Sin,Cos,0,0],\n\
249   [0,0,1,0],   \n\
250   [0,0,0,1]\n\
251   ];\n\
252   return MMulti(R, M);\n\
253 }\n\
254 \n\
255 function DrawQube() {\n\
256   // calc current normals\n\
257   var CurN = new Array();\n\
258   var i = 5;\n\
259   Q.LastPx = 0;\n\
260   for (; i > -1; i--) CurN[i] = VMulti2(MQube, Q.Normal[i]);\n\
261   if (CurN[0][2] < 0) {\n\
262     if (!Q.Line[0]) { DrawLine(Q[0], Q[1]); Q.Line[0] = true; };\n\
263     if (!Q.Line[1]) { DrawLine(Q[1], Q[2]); Q.Line[1] = true; };\n\
264     if (!Q.Line[2]) { DrawLine(Q[2], Q[3]); Q.Line[2] = true; };\n\
265     if (!Q.Line[3]) { DrawLine(Q[3], Q[0]); Q.Line[3] = true; };\n\
266   }\n\
267   if (CurN[1][2] < 0) {\n\
268     if (!Q.Line[2]) { DrawLine(Q[3], Q[2]); Q.Line[2] = true; };\n\
269     if (!Q.Line[9]) { DrawLine(Q[2], Q[6]); Q.Line[9] = true; };\n\
270     if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; };\n\
271     if (!Q.Line[10]) { DrawLine(Q[7], Q[3]); Q.Line[10] = true; };\n\
272   }\n\
273   if (CurN[2][2] < 0) {\n\
274     if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; };\n\
275     if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; };\n\
276     if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; };\n\
277     if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; };\n\
278   }\n\
279   if (CurN[3][2] < 0) {\n\
280     if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; };\n\
281     if (!Q.Line[8]) { DrawLine(Q[5], Q[1]); Q.Line[8] = true; };\n\
282     if (!Q.Line[0]) { DrawLine(Q[1], Q[0]); Q.Line[0] = true; };\n\
283     if (!Q.Line[11]) { DrawLine(Q[0], Q[4]); Q.Line[11] = true; };\n\
284   }\n\
285   if (CurN[4][2] < 0) {\n\
286     if (!Q.Line[11]) { DrawLine(Q[4], Q[0]); Q.Line[11] = true; };\n\
287     if (!Q.Line[3]) { DrawLine(Q[0], Q[3]); Q.Line[3] = true; };\n\
288     if (!Q.Line[10]) { DrawLine(Q[3], Q[7]); Q.Line[10] = true; };\n\
289     if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; };\n\
290   }\n\
291   if (CurN[5][2] < 0) {\n\
292     if (!Q.Line[8]) { DrawLine(Q[1], Q[5]); Q.Line[8] = true; };\n\
293     if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; };\n\
294     if (!Q.Line[9]) { DrawLine(Q[6], Q[2]); Q.Line[9] = true; };\n\
295     if (!Q.Line[1]) { DrawLine(Q[2], Q[1]); Q.Line[1] = true; };\n\
296   }\n\
297   Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false];\n\
298   Q.LastPx = 0;\n\
299 }\n\
300 \n\
301 function Loop() {\n\
302   if (Testing.LoopCount > Testing.LoopMax) return;\n\
303   var TestingStr = String(Testing.LoopCount);\n\
304   while (TestingStr.length < 3) TestingStr = \"0\" + TestingStr;\n\
305   MTrans = Translate(I, -Q[8].V[0], -Q[8].V[1], -Q[8].V[2]);\n\
306   MTrans = RotateX(MTrans, 1);\n\
307   MTrans = RotateY(MTrans, 3);\n\
308   MTrans = RotateZ(MTrans, 5);\n\
309   MTrans = Translate(MTrans, Q[8].V[0], Q[8].V[1], Q[8].V[2]);\n\
310   MQube = MMulti(MTrans, MQube);\n\
311   var i = 8;\n\
312   for (; i > -1; i--) {\n\
313     Q[i].V = VMulti(MTrans, Q[i].V);\n\
314   }\n\
315   DrawQube();\n\
316   Testing.LoopCount++;\n\
317   Loop();\n\
318 }\n\
319 \n\
320 function Init(CubeSize) {\n\
321   // init/reset vars\n\
322   Origin.V = [150,150,20,1];\n\
323   Testing.LoopCount = 0;\n\
324   Testing.LoopMax = 50;\n\
325   Testing.TimeMax = 0;\n\
326   Testing.TimeAvg = 0;\n\
327   Testing.TimeMin = 0;\n\
328   Testing.TimeTemp = 0;\n\
329   Testing.TimeTotal = 0;\n\
330   Testing.Init = false;\n\
331 \n\
332   // transformation matrix\n\
333   MTrans = [\n\
334   [1,0,0,0],\n\
335   [0,1,0,0],\n\
336   [0,0,1,0],\n\
337   [0,0,0,1]\n\
338   ];\n\
339   \n\
340   // position information of qube\n\
341   MQube = [\n\
342   [1,0,0,0],\n\
343   [0,1,0,0],\n\
344   [0,0,1,0],\n\
345   [0,0,0,1]\n\
346   ];\n\
347   \n\
348   // entity matrix\n\
349   I = [\n\
350   [1,0,0,0],\n\
351   [0,1,0,0],\n\
352   [0,0,1,0],\n\
353   [0,0,0,1]\n\
354   ];\n\
355   \n\
356   // create qube\n\
357   Q[0] = new CreateP(-CubeSize,-CubeSize, CubeSize);\n\
358   Q[1] = new CreateP(-CubeSize, CubeSize, CubeSize);\n\
359   Q[2] = new CreateP( CubeSize, CubeSize, CubeSize);\n\
360   Q[3] = new CreateP( CubeSize,-CubeSize, CubeSize);\n\
361   Q[4] = new CreateP(-CubeSize,-CubeSize,-CubeSize);\n\
362   Q[5] = new CreateP(-CubeSize, CubeSize,-CubeSize);\n\
363   Q[6] = new CreateP( CubeSize, CubeSize,-CubeSize);\n\
364   Q[7] = new CreateP( CubeSize,-CubeSize,-CubeSize);\n\
365   \n\
366   // center of gravity\n\
367   Q[8] = new CreateP(0, 0, 0);\n\
368   \n\
369   // anti-clockwise edge check\n\
370   Q.Edge = [[0,1,2],[3,2,6],[7,6,5],[4,5,1],[4,0,3],[1,5,6]];\n\
371   \n\
372   // calculate squad normals\n\
373   Q.Normal = new Array();\n\
374   for (var i = 0; i < Q.Edge.length; i++) Q.Normal[i] = CalcNormal(Q[Q.Edge[i][0]].V, Q[Q.Edge[i][1]].V, Q[Q.Edge[i][2]].V);\n\
375   \n\
376   // line drawn ?\n\
377   Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false];\n\
378   \n\
379   // create line pixels\n\
380   Q.NumPx = 9 * 2 * CubeSize;\n\
381   for (var i = 0; i < Q.NumPx; i++) CreateP(0,0,0);\n\
382   \n\
383   MTrans = Translate(MTrans, Origin.V[0], Origin.V[1], Origin.V[2]);\n\
384   MQube = MMulti(MTrans, MQube);\n\
385 \n\
386   var i = 0;\n\
387   for (; i < 9; i++) {\n\
388     Q[i].V = VMulti(MTrans, Q[i].V);\n\
389   }\n\
390   DrawQube();\n\
391   Testing.Init = true;\n\
392   Loop();\n\
393   \n\
394   // Perform a simple sum-based verification.\n\
395   var sum = 0;\n\
396   for (var i = 0; i < Q.length; ++i) {\n\
397     var vector = Q[i].V;\n\
398     for (var j = 0; j < vector.length; ++j)\n\
399       sum += vector[j];\n\
400   }\n\
401   if (sum != validation[CubeSize])\n\
402     throw \"Error: bad vector sum for CubeSize = \" + CubeSize + \"; expected \" + validation[CubeSize] + \" but got \" + sum;\n\
403 }\n\
404 \n\
405 for ( var i = 20; i <= 160; i *= 2 ) {\n\
406   Init(i);\n\
407 }\n\
408 \n\
409 Q = null;\n\
410 MTrans = null;\n\
411 MQube = null;\n\
412 I = null;\n\
413 Origin = null;\n\
414 Testing = null;\n\
415 LoopTime = null;\n\
416 DisplArea = null;\n\
417 \n\
418 \n\
419 \n\
420 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
421 \n\
422 record(_sunSpiderInterval);\n\
423 </script>\n\
424 \n\
425 \n\
426 </body>\n\
427 </html>\n\
428 ", "<!DOCTYPE html>\n\
429 <head>\n\
430 \n\
431 <meta charset=utf8>\n\
432 \n\
433 <!--\n\
434  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
435 \n\
436  Redistribution and use in source and binary forms, with or without\n\
437  modification, are permitted provided that the following conditions\n\
438  are met:\n\
439  1. Redistributions of source code must retain the above copyright\n\
440     notice, this list of conditions and the following disclaimer.\n\
441  2. Redistributions in binary form must reproduce the above copyright\n\
442     notice, this list of conditions and the following disclaimer in the\n\
443     documentation and/or other materials provided with the distribution.\n\
444 \n\
445  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
446  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
447  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
448  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
449  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
450  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
451  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
452  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
453  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
454  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
455  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
456 -->\n\
457 \n\
458 <title>SunSpider 3d-morph</title>\n\
459 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
460 <style>\n\
461 #countdown {\n\
462     font-size: 128px; \n\
463     text-align: center;\n\
464 }\n\
465 </style>\n\
466 </head>\n\
467 \n\
468 <body>\n\
469 <h3 id=\"countdown\"></h3>\n\
470 <script>\n\
471 if (window.parent) {\n\
472     document.getElementById(\"countdown\").innerHTML =\n\
473         window.parent.currentRepeat < 0\n\
474             ? \"warmup\"\n\
475             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
476 }\n\
477 \n\
478 function record(time) {\n\
479     if (window.parent)\n\
480         parent.recordResult(time);\n\
481 }\n\
482 \n\
483 window.onerror = function(e) {\n\
484     console.log(\"3d-morph failed with error: \" + e);\n\
485     record(0 / 0);\n\
486 }\n\
487 \n\
488 var _sunSpiderStartDate = new Date();\n\
489 \n\
490 /*\n\
491  * Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
492  *\n\
493  * Redistribution and use in source and binary forms, with or without\n\
494  * modification, are permitted provided that the following conditions\n\
495  * are met:\n\
496  * 1. Redistributions of source code must retain the above copyright\n\
497  *    notice, this list of conditions and the following disclaimer.\n\
498  * 2. Redistributions in binary form must reproduce the above copyright\n\
499  *    notice, this list of conditions and the following disclaimer in the\n\
500  *    documentation and/or other materials provided with the distribution.\n\
501  *\n\
502  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
503  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
504  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
505  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
506  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
507  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
508  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
509  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
510  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
511  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
512  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
513  */\n\
514 \n\
515 var loops = 15\n\
516 var nx = 120\n\
517 var nz = 120\n\
518 \n\
519 function morph(a, f) {\n\
520     var PI2nx = Math.PI * 8/nx\n\
521     var sin = Math.sin\n\
522     var f30 = -(50 * sin(f*Math.PI*2))\n\
523     \n\
524     for (var i = 0; i < nz; ++i) {\n\
525         for (var j = 0; j < nx; ++j) {\n\
526             a[3*(i*nx+j)+1]    = sin((j-1) * PI2nx ) * -f30\n\
527         }\n\
528     }\n\
529 }\n\
530 \n\
531     \n\
532 var a = Array()\n\
533 for (var i=0; i < nx*nz*3; ++i) \n\
534     a[i] = 0\n\
535 \n\
536 for (var i = 0; i < loops; ++i) {\n\
537     morph(a, i/loops)\n\
538 }\n\
539 \n\
540 testOutput = 0;\n\
541 for (var i = 0; i < nx; i++)\n\
542     testOutput += a[3*(i*nx+i)+1];\n\
543 a = null;\n\
544 \n\
545 // This has to be an approximate test since ECMAscript doesn't formally specify\n\
546 // what sin() returns. Even if it did specify something like for example what Java 7\n\
547 // says - that sin() has to return a value within 1 ulp of exact - then we still\n\
548 // would not be able to do an exact test here since that would allow for just enough\n\
549 // low-bit slop to create possibly big errors due to testOutput being a sum.\n\
550 var epsilon = 1e-13;\n\
551 if (Math.abs(testOutput) >= epsilon)\n\
552     throw \"Error: bad test output: expected magnitude below \" + epsilon + \" but got \" + testOutput;\n\
553 \n\
554 \n\
555 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
556 \n\
557 record(_sunSpiderInterval);\n\
558 </script>\n\
559 \n\
560 \n\
561 </body>\n\
562 </html>\n\
563 ", "<!DOCTYPE html>\n\
564 <head>\n\
565 \n\
566 <meta charset=utf8>\n\
567 \n\
568 <!--\n\
569  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
570 \n\
571  Redistribution and use in source and binary forms, with or without\n\
572  modification, are permitted provided that the following conditions\n\
573  are met:\n\
574  1. Redistributions of source code must retain the above copyright\n\
575     notice, this list of conditions and the following disclaimer.\n\
576  2. Redistributions in binary form must reproduce the above copyright\n\
577     notice, this list of conditions and the following disclaimer in the\n\
578     documentation and/or other materials provided with the distribution.\n\
579 \n\
580  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
581  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
582  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
583  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
584  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
585  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
586  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
587  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
588  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
589  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
590  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
591 -->\n\
592 \n\
593 <title>SunSpider 3d-raytrace</title>\n\
594 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
595 <style>\n\
596 #countdown {\n\
597     font-size: 128px; \n\
598     text-align: center;\n\
599 }\n\
600 </style>\n\
601 </head>\n\
602 \n\
603 <body>\n\
604 <h3 id=\"countdown\"></h3>\n\
605 <script>\n\
606 if (window.parent) {\n\
607     document.getElementById(\"countdown\").innerHTML =\n\
608         window.parent.currentRepeat < 0\n\
609             ? \"warmup\"\n\
610             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
611 }\n\
612 \n\
613 function record(time) {\n\
614     if (window.parent)\n\
615         parent.recordResult(time);\n\
616 }\n\
617 \n\
618 window.onerror = function(e) {\n\
619     console.log(\"3d-raytrace failed with error: \" + e);\n\
620     record(0 / 0);\n\
621 }\n\
622 \n\
623 var _sunSpiderStartDate = new Date();\n\
624 \n\
625 /*\n\
626  * Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
627  *\n\
628  * Redistribution and use in source and binary forms, with or without\n\
629  * modification, are permitted provided that the following conditions\n\
630  * are met:\n\
631  * 1. Redistributions of source code must retain the above copyright\n\
632  *    notice, this list of conditions and the following disclaimer.\n\
633  * 2. Redistributions in binary form must reproduce the above copyright\n\
634  *    notice, this list of conditions and the following disclaimer in the\n\
635  *    documentation and/or other materials provided with the distribution.\n\
636  *\n\
637  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
638  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
639  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
640  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
641  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
642  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
643  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
644  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
645  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
646  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
647  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
648  */\n\
649 \n\
650 function createVector(x,y,z) {\n\
651     return new Array(x,y,z);\n\
652 }\n\
653 \n\
654 function sqrLengthVector(self) {\n\
655     return self[0] * self[0] + self[1] * self[1] + self[2] * self[2];\n\
656 }\n\
657 \n\
658 function lengthVector(self) {\n\
659     return Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]);\n\
660 }\n\
661 \n\
662 function addVector(self, v) {\n\
663     self[0] += v[0];\n\
664     self[1] += v[1];\n\
665     self[2] += v[2];\n\
666     return self;\n\
667 }\n\
668 \n\
669 function subVector(self, v) {\n\
670     self[0] -= v[0];\n\
671     self[1] -= v[1];\n\
672     self[2] -= v[2];\n\
673     return self;\n\
674 }\n\
675 \n\
676 function scaleVector(self, scale) {\n\
677     self[0] *= scale;\n\
678     self[1] *= scale;\n\
679     self[2] *= scale;\n\
680     return self;\n\
681 }\n\
682 \n\
683 function normaliseVector(self) {\n\
684     var len = Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]);\n\
685     self[0] /= len;\n\
686     self[1] /= len;\n\
687     self[2] /= len;\n\
688     return self;\n\
689 }\n\
690 \n\
691 function add(v1, v2) {\n\
692     return new Array(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]);\n\
693 }\n\
694 \n\
695 function sub(v1, v2) {\n\
696     return new Array(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]);\n\
697 }\n\
698 \n\
699 function scalev(v1, v2) {\n\
700     return new Array(v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]);\n\
701 }\n\
702 \n\
703 function dot(v1, v2) {\n\
704     return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];\n\
705 }\n\
706 \n\
707 function scale(v, scale) {\n\
708     return [v[0] * scale, v[1] * scale, v[2] * scale];\n\
709 }\n\
710 \n\
711 function cross(v1, v2) {\n\
712     return [v1[1] * v2[2] - v1[2] * v2[1], \n\
713             v1[2] * v2[0] - v1[0] * v2[2],\n\
714             v1[0] * v2[1] - v1[1] * v2[0]];\n\
715 \n\
716 }\n\
717 \n\
718 function normalise(v) {\n\
719     var len = lengthVector(v);\n\
720     return [v[0] / len, v[1] / len, v[2] / len];\n\
721 }\n\
722 \n\
723 function transformMatrix(self, v) {\n\
724     var vals = self;\n\
725     var x  = vals[0] * v[0] + vals[1] * v[1] + vals[2] * v[2] + vals[3];\n\
726     var y  = vals[4] * v[0] + vals[5] * v[1] + vals[6] * v[2] + vals[7];\n\
727     var z  = vals[8] * v[0] + vals[9] * v[1] + vals[10] * v[2] + vals[11];\n\
728     return [x, y, z];\n\
729 }\n\
730 \n\
731 function invertMatrix(self) {\n\
732     var temp = new Array(16);\n\
733     var tx = -self[3];\n\
734     var ty = -self[7];\n\
735     var tz = -self[11];\n\
736     for (h = 0; h < 3; h++) \n\
737         for (v = 0; v < 3; v++) \n\
738             temp[h + v * 4] = self[v + h * 4];\n\
739     for (i = 0; i < 11; i++)\n\
740         self[i] = temp[i];\n\
741     self[3] = tx * self[0] + ty * self[1] + tz * self[2];\n\
742     self[7] = tx * self[4] + ty * self[5] + tz * self[6];\n\
743     self[11] = tx * self[8] + ty * self[9] + tz * self[10];\n\
744     return self;\n\
745 }\n\
746 \n\
747 \n\
748 // Triangle intersection using barycentric coord method\n\
749 function Triangle(p1, p2, p3) {\n\
750     var edge1 = sub(p3, p1);\n\
751     var edge2 = sub(p2, p1);\n\
752     var normal = cross(edge1, edge2);\n\
753     if (Math.abs(normal[0]) > Math.abs(normal[1]))\n\
754         if (Math.abs(normal[0]) > Math.abs(normal[2]))\n\
755             this.axis = 0; \n\
756         else \n\
757             this.axis = 2;\n\
758     else\n\
759         if (Math.abs(normal[1]) > Math.abs(normal[2])) \n\
760             this.axis = 1;\n\
761         else \n\
762             this.axis = 2;\n\
763     var u = (this.axis + 1) % 3;\n\
764     var v = (this.axis + 2) % 3;\n\
765     var u1 = edge1[u];\n\
766     var v1 = edge1[v];\n\
767     \n\
768     var u2 = edge2[u];\n\
769     var v2 = edge2[v];\n\
770     this.normal = normalise(normal);\n\
771     this.nu = normal[u] / normal[this.axis];\n\
772     this.nv = normal[v] / normal[this.axis];\n\
773     this.nd = dot(normal, p1) / normal[this.axis];\n\
774     var det = u1 * v2 - v1 * u2;\n\
775     this.eu = p1[u];\n\
776     this.ev = p1[v]; \n\
777     this.nu1 = u1 / det;\n\
778     this.nv1 = -v1 / det;\n\
779     this.nu2 = v2 / det;\n\
780     this.nv2 = -u2 / det; \n\
781     this.material = [0.7, 0.7, 0.7];\n\
782 }\n\
783 \n\
784 Triangle.prototype.intersect = function(orig, dir, near, far) {\n\
785     var u = (this.axis + 1) % 3;\n\
786     var v = (this.axis + 2) % 3;\n\
787     var d = dir[this.axis] + this.nu * dir[u] + this.nv * dir[v];\n\
788     var t = (this.nd - orig[this.axis] - this.nu * orig[u] - this.nv * orig[v]) / d;\n\
789     if (t < near || t > far)\n\
790         return null;\n\
791     var Pu = orig[u] + t * dir[u] - this.eu;\n\
792     var Pv = orig[v] + t * dir[v] - this.ev;\n\
793     var a2 = Pv * this.nu1 + Pu * this.nv1;\n\
794     if (a2 < 0) \n\
795         return null;\n\
796     var a3 = Pu * this.nu2 + Pv * this.nv2;\n\
797     if (a3 < 0) \n\
798         return null;\n\
799 \n\
800     if ((a2 + a3) > 1) \n\
801         return null;\n\
802     return t;\n\
803 }\n\
804 \n\
805 function Scene(a_triangles) {\n\
806     this.triangles = a_triangles;\n\
807     this.lights = [];\n\
808     this.ambient = [0,0,0];\n\
809     this.background = [0.8,0.8,1];\n\
810 }\n\
811 var zero = new Array(0,0,0);\n\
812 \n\
813 Scene.prototype.intersect = function(origin, dir, near, far) {\n\
814     var closest = null;\n\
815     for (i = 0; i < this.triangles.length; i++) {\n\
816         var triangle = this.triangles[i];   \n\
817         var d = triangle.intersect(origin, dir, near, far);\n\
818         if (d == null || d > far || d < near)\n\
819             continue;\n\
820         far = d;\n\
821         closest = triangle;\n\
822     }\n\
823     \n\
824     if (!closest)\n\
825         return [this.background[0],this.background[1],this.background[2]];\n\
826         \n\
827     var normal = closest.normal;\n\
828     var hit = add(origin, scale(dir, far)); \n\
829     if (dot(dir, normal) > 0)\n\
830         normal = [-normal[0], -normal[1], -normal[2]];\n\
831     \n\
832     var colour = null;\n\
833     if (closest.shader) {\n\
834         colour = closest.shader(closest, hit, dir);\n\
835     } else {\n\
836         colour = closest.material;\n\
837     }\n\
838     \n\
839     // do reflection\n\
840     var reflected = null;\n\
841     if (colour.reflection > 0.001) {\n\
842         var reflection = addVector(scale(normal, -2*dot(dir, normal)), dir);\n\
843         reflected = this.intersect(hit, reflection, 0.0001, 1000000);\n\
844         if (colour.reflection >= 0.999999)\n\
845             return reflected;\n\
846     }\n\
847     \n\
848     var l = [this.ambient[0], this.ambient[1], this.ambient[2]];\n\
849     for (var i = 0; i < this.lights.length; i++) {\n\
850         var light = this.lights[i];\n\
851         var toLight = sub(light, hit);\n\
852         var distance = lengthVector(toLight);\n\
853         scaleVector(toLight, 1.0/distance);\n\
854         distance -= 0.0001;\n\
855         if (this.blocked(hit, toLight, distance))\n\
856             continue;\n\
857         var nl = dot(normal, toLight);\n\
858         if (nl > 0)\n\
859             addVector(l, scale(light.colour, nl));\n\
860     }\n\
861     l = scalev(l, colour);\n\
862     if (reflected) {\n\
863         l = addVector(scaleVector(l, 1 - colour.reflection), scaleVector(reflected, colour.reflection));\n\
864     }\n\
865     return l;\n\
866 }\n\
867 \n\
868 Scene.prototype.blocked = function(O, D, far) {\n\
869     var near = 0.0001;\n\
870     var closest = null;\n\
871     for (i = 0; i < this.triangles.length; i++) {\n\
872         var triangle = this.triangles[i];   \n\
873         var d = triangle.intersect(O, D, near, far);\n\
874         if (d == null || d > far || d < near)\n\
875             continue;\n\
876         return true;\n\
877     }\n\
878     \n\
879     return false;\n\
880 }\n\
881 \n\
882 \n\
883 // this camera code is from notes i made ages ago, it is from *somewhere* -- i cannot remember where\n\
884 // that somewhere is\n\
885 function Camera(origin, lookat, up) {\n\
886     var zaxis = normaliseVector(subVector(lookat, origin));\n\
887     var xaxis = normaliseVector(cross(up, zaxis));\n\
888     var yaxis = normaliseVector(cross(xaxis, subVector([0,0,0], zaxis)));\n\
889     var m = new Array(16);\n\
890     m[0] = xaxis[0]; m[1] = xaxis[1]; m[2] = xaxis[2];\n\
891     m[4] = yaxis[0]; m[5] = yaxis[1]; m[6] = yaxis[2];\n\
892     m[8] = zaxis[0]; m[9] = zaxis[1]; m[10] = zaxis[2];\n\
893     invertMatrix(m);\n\
894     m[3] = 0; m[7] = 0; m[11] = 0;\n\
895     this.origin = origin;\n\
896     this.directions = new Array(4);\n\
897     this.directions[0] = normalise([-0.7,  0.7, 1]);\n\
898     this.directions[1] = normalise([ 0.7,  0.7, 1]);\n\
899     this.directions[2] = normalise([ 0.7, -0.7, 1]);\n\
900     this.directions[3] = normalise([-0.7, -0.7, 1]);\n\
901     this.directions[0] = transformMatrix(m, this.directions[0]);\n\
902     this.directions[1] = transformMatrix(m, this.directions[1]);\n\
903     this.directions[2] = transformMatrix(m, this.directions[2]);\n\
904     this.directions[3] = transformMatrix(m, this.directions[3]);\n\
905 }\n\
906 \n\
907 Camera.prototype.generateRayPair = function(y) {\n\
908     rays = new Array(new Object(), new Object());\n\
909     rays[0].origin = this.origin;\n\
910     rays[1].origin = this.origin;\n\
911     rays[0].dir = addVector(scale(this.directions[0], y), scale(this.directions[3], 1 - y));\n\
912     rays[1].dir = addVector(scale(this.directions[1], y), scale(this.directions[2], 1 - y));\n\
913     return rays;\n\
914 }\n\
915 \n\
916 function renderRows(camera, scene, pixels, width, height, starty, stopy) {\n\
917     for (var y = starty; y < stopy; y++) {\n\
918         var rays = camera.generateRayPair(y / height);\n\
919         for (var x = 0; x < width; x++) {\n\
920             var xp = x / width;\n\
921             var origin = addVector(scale(rays[0].origin, xp), scale(rays[1].origin, 1 - xp));\n\
922             var dir = normaliseVector(addVector(scale(rays[0].dir, xp), scale(rays[1].dir, 1 - xp)));\n\
923             var l = scene.intersect(origin, dir);\n\
924             pixels[y][x] = l;\n\
925         }\n\
926     }\n\
927 }\n\
928 \n\
929 Camera.prototype.render = function(scene, pixels, width, height) {\n\
930     var cam = this;\n\
931     var row = 0;\n\
932     renderRows(cam, scene, pixels, width, height, 0, height);\n\
933 }\n\
934 \n\
935 \n\
936 \n\
937 function raytraceScene()\n\
938 {\n\
939     var startDate = new Date().getTime();\n\
940     var numTriangles = 2 * 6;\n\
941     var triangles = new Array();//numTriangles);\n\
942     var tfl = createVector(-10,  10, -10);\n\
943     var tfr = createVector( 10,  10, -10);\n\
944     var tbl = createVector(-10,  10,  10);\n\
945     var tbr = createVector( 10,  10,  10);\n\
946     var bfl = createVector(-10, -10, -10);\n\
947     var bfr = createVector( 10, -10, -10);\n\
948     var bbl = createVector(-10, -10,  10);\n\
949     var bbr = createVector( 10, -10,  10);\n\
950     \n\
951     // cube!!!\n\
952     // front\n\
953     var i = 0;\n\
954     \n\
955     triangles[i++] = new Triangle(tfl, tfr, bfr);\n\
956     triangles[i++] = new Triangle(tfl, bfr, bfl);\n\
957     // back\n\
958     triangles[i++] = new Triangle(tbl, tbr, bbr);\n\
959     triangles[i++] = new Triangle(tbl, bbr, bbl);\n\
960     //        triangles[i-1].material = [0.7,0.2,0.2];\n\
961     //            triangles[i-1].material.reflection = 0.8;\n\
962     // left\n\
963     triangles[i++] = new Triangle(tbl, tfl, bbl);\n\
964     //            triangles[i-1].reflection = 0.6;\n\
965     triangles[i++] = new Triangle(tfl, bfl, bbl);\n\
966     //            triangles[i-1].reflection = 0.6;\n\
967     // right\n\
968     triangles[i++] = new Triangle(tbr, tfr, bbr);\n\
969     triangles[i++] = new Triangle(tfr, bfr, bbr);\n\
970     // top\n\
971     triangles[i++] = new Triangle(tbl, tbr, tfr);\n\
972     triangles[i++] = new Triangle(tbl, tfr, tfl);\n\
973     // bottom\n\
974     triangles[i++] = new Triangle(bbl, bbr, bfr);\n\
975     triangles[i++] = new Triangle(bbl, bfr, bfl);\n\
976     \n\
977     //Floor!!!!\n\
978     var green = createVector(0.0, 0.4, 0.0);\n\
979     var grey = createVector(0.4, 0.4, 0.4);\n\
980     grey.reflection = 1.0;\n\
981     var floorShader = function(tri, pos, view) {\n\
982         var x = ((pos[0]/32) % 2 + 2) % 2;\n\
983         var z = ((pos[2]/32 + 0.3) % 2 + 2) % 2;\n\
984         if (x < 1 != z < 1) {\n\
985             //in the real world we use the fresnel term...\n\
986             //    var angle = 1-dot(view, tri.normal);\n\
987             //   angle *= angle;\n\
988             //  angle *= angle;\n\
989             // angle *= angle;\n\
990             //grey.reflection = angle;\n\
991             return grey;\n\
992         } else \n\
993             return green;\n\
994     }\n\
995     var ffl = createVector(-1000, -30, -1000);\n\
996     var ffr = createVector( 1000, -30, -1000);\n\
997     var fbl = createVector(-1000, -30,  1000);\n\
998     var fbr = createVector( 1000, -30,  1000);\n\
999     triangles[i++] = new Triangle(fbl, fbr, ffr);\n\
1000     triangles[i-1].shader = floorShader;\n\
1001     triangles[i++] = new Triangle(fbl, ffr, ffl);\n\
1002     triangles[i-1].shader = floorShader;\n\
1003     \n\
1004     var _scene = new Scene(triangles);\n\
1005     _scene.lights[0] = createVector(20, 38, -22);\n\
1006     _scene.lights[0].colour = createVector(0.7, 0.3, 0.3);\n\
1007     _scene.lights[1] = createVector(-23, 40, 17);\n\
1008     _scene.lights[1].colour = createVector(0.7, 0.3, 0.3);\n\
1009     _scene.lights[2] = createVector(23, 20, 17);\n\
1010     _scene.lights[2].colour = createVector(0.7, 0.7, 0.7);\n\
1011     _scene.ambient = createVector(0.1, 0.1, 0.1);\n\
1012     //  _scene.background = createVector(0.7, 0.7, 1.0);\n\
1013     \n\
1014     var size = 30;\n\
1015     var pixels = new Array();\n\
1016     for (var y = 0; y < size; y++) {\n\
1017         pixels[y] = new Array();\n\
1018         for (var x = 0; x < size; x++) {\n\
1019             pixels[y][x] = 0;\n\
1020         }\n\
1021     }\n\
1022 \n\
1023     var _camera = new Camera(createVector(-40, 40, 40), createVector(0, 0, 0), createVector(0, 1, 0));\n\
1024     _camera.render(_scene, pixels, size, size);\n\
1025 \n\
1026     return pixels;\n\
1027 }\n\
1028 \n\
1029 function arrayToCanvasCommands(pixels)\n\
1030 {\n\
1031     var s = '<canvas id=\"renderCanvas\" width=\"30px\" height=\"30px\"></canvas><scr' + 'ipt>\\nvar pixels = [';\n\
1032     var size = 30;\n\
1033     for (var y = 0; y < size; y++) {\n\
1034         s += \"[\";\n\
1035         for (var x = 0; x < size; x++) {\n\
1036             s += \"[\" + pixels[y][x] + \"],\";\n\
1037         }\n\
1038         s+= \"],\";\n\
1039     }\n\
1040     s += '];\\n    var canvas = document.getElementById(\"renderCanvas\").getContext(\"2d\");\\n\\\n\
1041 \\n\\\n\
1042 \\n\\\n\
1043     var size = 30;\\n\\\n\
1044     canvas.fillStyle = \"red\";\\n\\\n\
1045     canvas.fillRect(0, 0, size, size);\\n\\\n\
1046     canvas.scale(1, -1);\\n\\\n\
1047     canvas.translate(0, -size);\\n\\\n\
1048 \\n\\\n\
1049     if (!canvas.setFillColor)\\n\\\n\
1050         canvas.setFillColor = function(r, g, b, a) {\\n\\\n\
1051             this.fillStyle = \"rgb(\"+[Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)]+\")\";\\n\\\n\
1052     }\\n\\\n\
1053 \\n\\\n\
1054 for (var y = 0; y < size; y++) {\\n\\\n\
1055   for (var x = 0; x < size; x++) {\\n\\\n\
1056     var l = pixels[y][x];\\n\\\n\
1057     canvas.setFillColor(l[0], l[1], l[2], 1);\\n\\\n\
1058     canvas.fillRect(x, y, 1, 1);\\n\\\n\
1059   }\\n\\\n\
1060 }</scr' + 'ipt>';\n\
1061 \n\
1062     return s;\n\
1063 }\n\
1064 \n\
1065 testOutput = arrayToCanvasCommands(raytraceScene());\n\
1066 \n\
1067 var expectedLength = 20970;\n\
1068 \n\
1069 if (testOutput.length != expectedLength)\n\
1070     throw \"Error: bad result: expected length \" + expectedLength + \" but got \" + testOutput.length;\n\
1071 \n\
1072 \n\
1073 \n\
1074 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1075 \n\
1076 record(_sunSpiderInterval);\n\
1077 </script>\n\
1078 \n\
1079 \n\
1080 </body>\n\
1081 </html>\n\
1082 ", "<!DOCTYPE html>\n\
1083 <head>\n\
1084 \n\
1085 <meta charset=utf8>\n\
1086 \n\
1087 <!--\n\
1088  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1089 \n\
1090  Redistribution and use in source and binary forms, with or without\n\
1091  modification, are permitted provided that the following conditions\n\
1092  are met:\n\
1093  1. Redistributions of source code must retain the above copyright\n\
1094     notice, this list of conditions and the following disclaimer.\n\
1095  2. Redistributions in binary form must reproduce the above copyright\n\
1096     notice, this list of conditions and the following disclaimer in the\n\
1097     documentation and/or other materials provided with the distribution.\n\
1098 \n\
1099  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1100  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1101  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1102  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1103  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1104  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1105  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1106  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1107  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1108  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1109  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1110 -->\n\
1111 \n\
1112 <title>SunSpider access-binary-trees</title>\n\
1113 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1114 <style>\n\
1115 #countdown {\n\
1116     font-size: 128px; \n\
1117     text-align: center;\n\
1118 }\n\
1119 </style>\n\
1120 </head>\n\
1121 \n\
1122 <body>\n\
1123 <h3 id=\"countdown\"></h3>\n\
1124 <script>\n\
1125 if (window.parent) {\n\
1126     document.getElementById(\"countdown\").innerHTML =\n\
1127         window.parent.currentRepeat < 0\n\
1128             ? \"warmup\"\n\
1129             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
1130 }\n\
1131 \n\
1132 function record(time) {\n\
1133     if (window.parent)\n\
1134         parent.recordResult(time);\n\
1135 }\n\
1136 \n\
1137 window.onerror = function(e) {\n\
1138     console.log(\"access-binary-trees failed with error: \" + e);\n\
1139     record(0 / 0);\n\
1140 }\n\
1141 \n\
1142 var _sunSpiderStartDate = new Date();\n\
1143 \n\
1144 /* The Great Computer Language Shootout\n\
1145    http://shootout.alioth.debian.org/\n\
1146    contributed by Isaac Gouy */\n\
1147 \n\
1148 function TreeNode(left,right,item){\n\
1149    this.left = left;\n\
1150    this.right = right;\n\
1151    this.item = item;\n\
1152 }\n\
1153 \n\
1154 TreeNode.prototype.itemCheck = function(){\n\
1155    if (this.left==null) return this.item;\n\
1156    else return this.item + this.left.itemCheck() - this.right.itemCheck();\n\
1157 }\n\
1158 \n\
1159 function bottomUpTree(item,depth){\n\
1160    if (depth>0){\n\
1161       return new TreeNode(\n\
1162           bottomUpTree(2*item-1, depth-1)\n\
1163          ,bottomUpTree(2*item, depth-1)\n\
1164          ,item\n\
1165       );\n\
1166    }\n\
1167    else {\n\
1168       return new TreeNode(null,null,item);\n\
1169    }\n\
1170 }\n\
1171 \n\
1172 var ret = 0;\n\
1173 \n\
1174 for ( var n = 4; n <= 7; n += 1 ) {\n\
1175     var minDepth = 4;\n\
1176     var maxDepth = Math.max(minDepth + 2, n);\n\
1177     var stretchDepth = maxDepth + 1;\n\
1178     \n\
1179     var check = bottomUpTree(0,stretchDepth).itemCheck();\n\
1180     \n\
1181     var longLivedTree = bottomUpTree(0,maxDepth);\n\
1182     for (var depth=minDepth; depth<=maxDepth; depth+=2){\n\
1183         var iterations = 1 << (maxDepth - depth + minDepth);\n\
1184 \n\
1185         check = 0;\n\
1186         for (var i=1; i<=iterations; i++){\n\
1187             check += bottomUpTree(i,depth).itemCheck();\n\
1188             check += bottomUpTree(-i,depth).itemCheck();\n\
1189         }\n\
1190     }\n\
1191 \n\
1192     ret += longLivedTree.itemCheck();\n\
1193 }\n\
1194 \n\
1195 var expected = -4;\n\
1196 if (ret != expected)\n\
1197     throw \"ERROR: bad result: expected \" + expected + \" but got \" + ret;\n\
1198 \n\
1199 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1200 \n\
1201 record(_sunSpiderInterval);\n\
1202 </script>\n\
1203 \n\
1204 \n\
1205 </body>\n\
1206 </html>\n\
1207 ", "<!DOCTYPE html>\n\
1208 <head>\n\
1209 \n\
1210 <meta charset=utf8>\n\
1211 \n\
1212 <!--\n\
1213  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1214 \n\
1215  Redistribution and use in source and binary forms, with or without\n\
1216  modification, are permitted provided that the following conditions\n\
1217  are met:\n\
1218  1. Redistributions of source code must retain the above copyright\n\
1219     notice, this list of conditions and the following disclaimer.\n\
1220  2. Redistributions in binary form must reproduce the above copyright\n\
1221     notice, this list of conditions and the following disclaimer in the\n\
1222     documentation and/or other materials provided with the distribution.\n\
1223 \n\
1224  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1225  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1226  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1227  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1228  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1229  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1230  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1231  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1232  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1233  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1234  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1235 -->\n\
1236 \n\
1237 <title>SunSpider access-fannkuch</title>\n\
1238 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1239 <style>\n\
1240 #countdown {\n\
1241     font-size: 128px; \n\
1242     text-align: center;\n\
1243 }\n\
1244 </style>\n\
1245 </head>\n\
1246 \n\
1247 <body>\n\
1248 <h3 id=\"countdown\"></h3>\n\
1249 <script>\n\
1250 if (window.parent) {\n\
1251     document.getElementById(\"countdown\").innerHTML =\n\
1252         window.parent.currentRepeat < 0\n\
1253             ? \"warmup\"\n\
1254             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
1255 }\n\
1256 \n\
1257 function record(time) {\n\
1258     if (window.parent)\n\
1259         parent.recordResult(time);\n\
1260 }\n\
1261 \n\
1262 window.onerror = function(e) {\n\
1263     console.log(\"access-fannkuch failed with error: \" + e);\n\
1264     record(0 / 0);\n\
1265 }\n\
1266 \n\
1267 var _sunSpiderStartDate = new Date();\n\
1268 \n\
1269 /* The Great Computer Language Shootout\n\
1270    http://shootout.alioth.debian.org/\n\
1271    contributed by Isaac Gouy */\n\
1272 \n\
1273 function fannkuch(n) {\n\
1274    var check = 0;\n\
1275    var perm = Array(n);\n\
1276    var perm1 = Array(n);\n\
1277    var count = Array(n);\n\
1278    var maxPerm = Array(n);\n\
1279    var maxFlipsCount = 0;\n\
1280    var m = n - 1;\n\
1281 \n\
1282    for (var i = 0; i < n; i++) perm1[i] = i;\n\
1283    var r = n;\n\
1284 \n\
1285    while (true) {\n\
1286       // write-out the first 30 permutations\n\
1287       if (check < 30){\n\
1288          var s = \"\";\n\
1289          for(var i=0; i<n; i++) s += (perm1[i]+1).toString();\n\
1290          check++;\n\
1291       }\n\
1292 \n\
1293       while (r != 1) { count[r - 1] = r; r--; }\n\
1294       if (!(perm1[0] == 0 || perm1[m] == m)) {\n\
1295          for (var i = 0; i < n; i++) perm[i] = perm1[i];\n\
1296 \n\
1297          var flipsCount = 0;\n\
1298          var k;\n\
1299 \n\
1300          while (!((k = perm[0]) == 0)) {\n\
1301             var k2 = (k + 1) >> 1;\n\
1302             for (var i = 0; i < k2; i++) {\n\
1303                var temp = perm[i]; perm[i] = perm[k - i]; perm[k - i] = temp;\n\
1304             }\n\
1305             flipsCount++;\n\
1306          }\n\
1307 \n\
1308          if (flipsCount > maxFlipsCount) {\n\
1309             maxFlipsCount = flipsCount;\n\
1310             for (var i = 0; i < n; i++) maxPerm[i] = perm1[i];\n\
1311          }\n\
1312       }\n\
1313 \n\
1314       while (true) {\n\
1315          if (r == n) return maxFlipsCount;\n\
1316          var perm0 = perm1[0];\n\
1317          var i = 0;\n\
1318          while (i < r) {\n\
1319             var j = i + 1;\n\
1320             perm1[i] = perm1[j];\n\
1321             i = j;\n\
1322          }\n\
1323          perm1[r] = perm0;\n\
1324 \n\
1325          count[r] = count[r] - 1;\n\
1326          if (count[r] > 0) break;\n\
1327          r++;\n\
1328       }\n\
1329    }\n\
1330 }\n\
1331 \n\
1332 var n = 8;\n\
1333 var ret = fannkuch(n);\n\
1334 \n\
1335 var expected = 22;\n\
1336 if (ret != expected)\n\
1337     throw \"ERROR: bad result: expected \" + expected + \" but got \" + ret;\n\
1338 \n\
1339 \n\
1340 \n\
1341 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1342 \n\
1343 record(_sunSpiderInterval);\n\
1344 </script>\n\
1345 \n\
1346 \n\
1347 </body>\n\
1348 </html>\n\
1349 ", "<!DOCTYPE html>\n\
1350 <head>\n\
1351 \n\
1352 <meta charset=utf8>\n\
1353 \n\
1354 <!--\n\
1355  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1356 \n\
1357  Redistribution and use in source and binary forms, with or without\n\
1358  modification, are permitted provided that the following conditions\n\
1359  are met:\n\
1360  1. Redistributions of source code must retain the above copyright\n\
1361     notice, this list of conditions and the following disclaimer.\n\
1362  2. Redistributions in binary form must reproduce the above copyright\n\
1363     notice, this list of conditions and the following disclaimer in the\n\
1364     documentation and/or other materials provided with the distribution.\n\
1365 \n\
1366  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1367  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1368  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1369  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1370  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1371  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1372  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1373  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1374  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1375  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1376  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1377 -->\n\
1378 \n\
1379 <title>SunSpider access-nbody</title>\n\
1380 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1381 <style>\n\
1382 #countdown {\n\
1383     font-size: 128px; \n\
1384     text-align: center;\n\
1385 }\n\
1386 </style>\n\
1387 </head>\n\
1388 \n\
1389 <body>\n\
1390 <h3 id=\"countdown\"></h3>\n\
1391 <script>\n\
1392 if (window.parent) {\n\
1393     document.getElementById(\"countdown\").innerHTML =\n\
1394         window.parent.currentRepeat < 0\n\
1395             ? \"warmup\"\n\
1396             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
1397 }\n\
1398 \n\
1399 function record(time) {\n\
1400     if (window.parent)\n\
1401         parent.recordResult(time);\n\
1402 }\n\
1403 \n\
1404 window.onerror = function(e) {\n\
1405     console.log(\"access-nbody failed with error: \" + e);\n\
1406     record(0 / 0);\n\
1407 }\n\
1408 \n\
1409 var _sunSpiderStartDate = new Date();\n\
1410 \n\
1411 /* The Great Computer Language Shootout\n\
1412    http://shootout.alioth.debian.org/\n\
1413    contributed by Isaac Gouy */\n\
1414 \n\
1415 var PI = 3.141592653589793;\n\
1416 var SOLAR_MASS = 4 * PI * PI;\n\
1417 var DAYS_PER_YEAR = 365.24;\n\
1418 \n\
1419 function Body(x,y,z,vx,vy,vz,mass){\n\
1420    this.x = x;\n\
1421    this.y = y;\n\
1422    this.z = z;\n\
1423    this.vx = vx;\n\
1424    this.vy = vy;\n\
1425    this.vz = vz;\n\
1426    this.mass = mass;\n\
1427 }\n\
1428 \n\
1429 Body.prototype.offsetMomentum = function(px,py,pz) {\n\
1430    this.vx = -px / SOLAR_MASS;\n\
1431    this.vy = -py / SOLAR_MASS;\n\
1432    this.vz = -pz / SOLAR_MASS;\n\
1433    return this;\n\
1434 }\n\
1435 \n\
1436 function Jupiter(){\n\
1437    return new Body(\n\
1438       4.84143144246472090e+00,\n\
1439       -1.16032004402742839e+00,\n\
1440       -1.03622044471123109e-01,\n\
1441       1.66007664274403694e-03 * DAYS_PER_YEAR,\n\
1442       7.69901118419740425e-03 * DAYS_PER_YEAR,\n\
1443       -6.90460016972063023e-05 * DAYS_PER_YEAR,\n\
1444       9.54791938424326609e-04 * SOLAR_MASS\n\
1445    );\n\
1446 }\n\
1447 \n\
1448 function Saturn(){\n\
1449    return new Body(\n\
1450       8.34336671824457987e+00,\n\
1451       4.12479856412430479e+00,\n\
1452       -4.03523417114321381e-01,\n\
1453       -2.76742510726862411e-03 * DAYS_PER_YEAR,\n\
1454       4.99852801234917238e-03 * DAYS_PER_YEAR,\n\
1455       2.30417297573763929e-05 * DAYS_PER_YEAR,\n\
1456       2.85885980666130812e-04 * SOLAR_MASS\n\
1457    );\n\
1458 }\n\
1459 \n\
1460 function Uranus(){\n\
1461    return new Body(\n\
1462       1.28943695621391310e+01,\n\
1463       -1.51111514016986312e+01,\n\
1464       -2.23307578892655734e-01,\n\
1465       2.96460137564761618e-03 * DAYS_PER_YEAR,\n\
1466       2.37847173959480950e-03 * DAYS_PER_YEAR,\n\
1467       -2.96589568540237556e-05 * DAYS_PER_YEAR,\n\
1468       4.36624404335156298e-05 * SOLAR_MASS\n\
1469    );\n\
1470 }\n\
1471 \n\
1472 function Neptune(){\n\
1473    return new Body(\n\
1474       1.53796971148509165e+01,\n\
1475       -2.59193146099879641e+01,\n\
1476       1.79258772950371181e-01,\n\
1477       2.68067772490389322e-03 * DAYS_PER_YEAR,\n\
1478       1.62824170038242295e-03 * DAYS_PER_YEAR,\n\
1479       -9.51592254519715870e-05 * DAYS_PER_YEAR,\n\
1480       5.15138902046611451e-05 * SOLAR_MASS\n\
1481    );\n\
1482 }\n\
1483 \n\
1484 function Sun(){\n\
1485    return new Body(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS);\n\
1486 }\n\
1487 \n\
1488 \n\
1489 function NBodySystem(bodies){\n\
1490    this.bodies = bodies;\n\
1491    var px = 0.0;\n\
1492    var py = 0.0;\n\
1493    var pz = 0.0;\n\
1494    var size = this.bodies.length;\n\
1495    for (var i=0; i<size; i++){\n\
1496       var b = this.bodies[i];\n\
1497       var m = b.mass;\n\
1498       px += b.vx * m;\n\
1499       py += b.vy * m;\n\
1500       pz += b.vz * m;\n\
1501    }\n\
1502    this.bodies[0].offsetMomentum(px,py,pz);\n\
1503 }\n\
1504 \n\
1505 NBodySystem.prototype.advance = function(dt){\n\
1506    var dx, dy, dz, distance, mag;\n\
1507    var size = this.bodies.length;\n\
1508 \n\
1509    for (var i=0; i<size; i++) {\n\
1510       var bodyi = this.bodies[i];\n\
1511       for (var j=i+1; j<size; j++) {\n\
1512          var bodyj = this.bodies[j];\n\
1513          dx = bodyi.x - bodyj.x;\n\
1514          dy = bodyi.y - bodyj.y;\n\
1515          dz = bodyi.z - bodyj.z;\n\
1516 \n\
1517          distance = Math.sqrt(dx*dx + dy*dy + dz*dz);\n\
1518          mag = dt / (distance * distance * distance);\n\
1519 \n\
1520          bodyi.vx -= dx * bodyj.mass * mag;\n\
1521          bodyi.vy -= dy * bodyj.mass * mag;\n\
1522          bodyi.vz -= dz * bodyj.mass * mag;\n\
1523 \n\
1524          bodyj.vx += dx * bodyi.mass * mag;\n\
1525          bodyj.vy += dy * bodyi.mass * mag;\n\
1526          bodyj.vz += dz * bodyi.mass * mag;\n\
1527       }\n\
1528    }\n\
1529 \n\
1530    for (var i=0; i<size; i++) {\n\
1531       var body = this.bodies[i];\n\
1532       body.x += dt * body.vx;\n\
1533       body.y += dt * body.vy;\n\
1534       body.z += dt * body.vz;\n\
1535    }\n\
1536 }\n\
1537 \n\
1538 NBodySystem.prototype.energy = function(){\n\
1539    var dx, dy, dz, distance;\n\
1540    var e = 0.0;\n\
1541    var size = this.bodies.length;\n\
1542 \n\
1543    for (var i=0; i<size; i++) {\n\
1544       var bodyi = this.bodies[i];\n\
1545 \n\
1546       e += 0.5 * bodyi.mass *\n\
1547          ( bodyi.vx * bodyi.vx\n\
1548          + bodyi.vy * bodyi.vy\n\
1549          + bodyi.vz * bodyi.vz );\n\
1550 \n\
1551       for (var j=i+1; j<size; j++) {\n\
1552          var bodyj = this.bodies[j];\n\
1553          dx = bodyi.x - bodyj.x;\n\
1554          dy = bodyi.y - bodyj.y;\n\
1555          dz = bodyi.z - bodyj.z;\n\
1556 \n\
1557          distance = Math.sqrt(dx*dx + dy*dy + dz*dz);\n\
1558          e -= (bodyi.mass * bodyj.mass) / distance;\n\
1559       }\n\
1560    }\n\
1561    return e;\n\
1562 }\n\
1563 \n\
1564 var ret = 0;\n\
1565 \n\
1566 for ( var n = 3; n <= 24; n *= 2 ) {\n\
1567     (function(){\n\
1568         var bodies = new NBodySystem( Array(\n\
1569            Sun(),Jupiter(),Saturn(),Uranus(),Neptune()\n\
1570         ));\n\
1571         var max = n * 100;\n\
1572         \n\
1573         ret += bodies.energy();\n\
1574         for (var i=0; i<max; i++){\n\
1575             bodies.advance(0.01);\n\
1576         }\n\
1577         ret += bodies.energy();\n\
1578     })();\n\
1579 }\n\
1580 \n\
1581 var expected = -1.3524862408537381;\n\
1582 if (ret != expected)\n\
1583     throw \"ERROR: bad result: expected \" + expected + \" but got \" + ret;\n\
1584 \n\
1585 \n\
1586 \n\
1587 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1588 \n\
1589 record(_sunSpiderInterval);\n\
1590 </script>\n\
1591 \n\
1592 \n\
1593 </body>\n\
1594 </html>\n\
1595 ", "<!DOCTYPE html>\n\
1596 <head>\n\
1597 \n\
1598 <meta charset=utf8>\n\
1599 \n\
1600 <!--\n\
1601  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1602 \n\
1603  Redistribution and use in source and binary forms, with or without\n\
1604  modification, are permitted provided that the following conditions\n\
1605  are met:\n\
1606  1. Redistributions of source code must retain the above copyright\n\
1607     notice, this list of conditions and the following disclaimer.\n\
1608  2. Redistributions in binary form must reproduce the above copyright\n\
1609     notice, this list of conditions and the following disclaimer in the\n\
1610     documentation and/or other materials provided with the distribution.\n\
1611 \n\
1612  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1613  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1614  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1615  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1616  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1617  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1618  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1619  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1620  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1621  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1622  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1623 -->\n\
1624 \n\
1625 <title>SunSpider access-nsieve</title>\n\
1626 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1627 <style>\n\
1628 #countdown {\n\
1629     font-size: 128px; \n\
1630     text-align: center;\n\
1631 }\n\
1632 </style>\n\
1633 </head>\n\
1634 \n\
1635 <body>\n\
1636 <h3 id=\"countdown\"></h3>\n\
1637 <script>\n\
1638 if (window.parent) {\n\
1639     document.getElementById(\"countdown\").innerHTML =\n\
1640         window.parent.currentRepeat < 0\n\
1641             ? \"warmup\"\n\
1642             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
1643 }\n\
1644 \n\
1645 function record(time) {\n\
1646     if (window.parent)\n\
1647         parent.recordResult(time);\n\
1648 }\n\
1649 \n\
1650 window.onerror = function(e) {\n\
1651     console.log(\"access-nsieve failed with error: \" + e);\n\
1652     record(0 / 0);\n\
1653 }\n\
1654 \n\
1655 var _sunSpiderStartDate = new Date();\n\
1656 \n\
1657 // The Great Computer Language Shootout\n\
1658 // http://shootout.alioth.debian.org/\n\
1659 //\n\
1660 // modified by Isaac Gouy\n\
1661 \n\
1662 function pad(number,width){\n\
1663    var s = number.toString();\n\
1664    var prefixWidth = width - s.length;\n\
1665    if (prefixWidth>0){\n\
1666       for (var i=1; i<=prefixWidth; i++) s = \" \" + s;\n\
1667    }\n\
1668    return s;\n\
1669 }\n\
1670 \n\
1671 function nsieve(m, isPrime){\n\
1672    var i, k, count;\n\
1673 \n\
1674    for (i=2; i<=m; i++) { isPrime[i] = true; }\n\
1675    count = 0;\n\
1676 \n\
1677    for (i=2; i<=m; i++){\n\
1678       if (isPrime[i]) {\n\
1679          for (k=i+i; k<=m; k+=i) isPrime[k] = false;\n\
1680          count++;\n\
1681       }\n\
1682    }\n\
1683    return count;\n\
1684 }\n\
1685 \n\
1686 function sieve() {\n\
1687     var sum = 0;\n\
1688     for (var i = 1; i <= 3; i++ ) {\n\
1689         var m = (1<<i)*10000;\n\
1690         var flags = Array(m+1);\n\
1691         sum += nsieve(m, flags);\n\
1692     }\n\
1693     return sum;\n\
1694 }\n\
1695 \n\
1696 var result = sieve();\n\
1697 \n\
1698 var expected = 14302;\n\
1699 if (result != expected)\n\
1700     throw \"ERROR: bad result: expected \" + expected + \" but got \" + result;\n\
1701 \n\
1702 \n\
1703 \n\
1704 \n\
1705 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1706 \n\
1707 record(_sunSpiderInterval);\n\
1708 </script>\n\
1709 \n\
1710 \n\
1711 </body>\n\
1712 </html>\n\
1713 ", "<!DOCTYPE html>\n\
1714 <head>\n\
1715 \n\
1716 <meta charset=utf8>\n\
1717 \n\
1718 <!--\n\
1719  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1720 \n\
1721  Redistribution and use in source and binary forms, with or without\n\
1722  modification, are permitted provided that the following conditions\n\
1723  are met:\n\
1724  1. Redistributions of source code must retain the above copyright\n\
1725     notice, this list of conditions and the following disclaimer.\n\
1726  2. Redistributions in binary form must reproduce the above copyright\n\
1727     notice, this list of conditions and the following disclaimer in the\n\
1728     documentation and/or other materials provided with the distribution.\n\
1729 \n\
1730  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1731  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1732  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1733  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1734  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1735  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1736  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1737  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1738  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1739  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1740  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1741 -->\n\
1742 \n\
1743 <title>SunSpider bitops-3bit-bits-in-byte</title>\n\
1744 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1745 <style>\n\
1746 #countdown {\n\
1747     font-size: 128px; \n\
1748     text-align: center;\n\
1749 }\n\
1750 </style>\n\
1751 </head>\n\
1752 \n\
1753 <body>\n\
1754 <h3 id=\"countdown\"></h3>\n\
1755 <script>\n\
1756 if (window.parent) {\n\
1757     document.getElementById(\"countdown\").innerHTML =\n\
1758         window.parent.currentRepeat < 0\n\
1759             ? \"warmup\"\n\
1760             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
1761 }\n\
1762 \n\
1763 function record(time) {\n\
1764     if (window.parent)\n\
1765         parent.recordResult(time);\n\
1766 }\n\
1767 \n\
1768 window.onerror = function(e) {\n\
1769     console.log(\"bitops-3bit-bits-in-byte failed with error: \" + e);\n\
1770     record(0 / 0);\n\
1771 }\n\
1772 \n\
1773 var _sunSpiderStartDate = new Date();\n\
1774 \n\
1775 // Copyright (c) 2004 by Arthur Langereis (arthur_ext at domain xfinitegames, tld com\n\
1776 \n\
1777 var result = 0;\n\
1778 \n\
1779 // 1 op = 6 ANDs, 3 SHRs, 3 SHLs, 4 assigns, 2 ADDs\n\
1780 // O(1)\n\
1781 function fast3bitlookup(b) {\n\
1782 var c, bi3b = 0xE994; // 0b1110 1001 1001 0100; // 3 2 2 1  2 1 1 0\n\
1783 c  = 3 & (bi3b >> ((b << 1) & 14));\n\
1784 c += 3 & (bi3b >> ((b >> 2) & 14));\n\
1785 c += 3 & (bi3b >> ((b >> 5) & 6));\n\
1786 return c;\n\
1787 \n\
1788 /*\n\
1789 lir4,0xE994; 9 instructions, no memory access, minimal register dependence, 6 shifts, 2 adds, 1 inline assign\n\
1790 rlwinmr5,r3,1,28,30\n\
1791 rlwinmr6,r3,30,28,30\n\
1792 rlwinmr7,r3,27,29,30\n\
1793 rlwnmr8,r4,r5,30,31\n\
1794 rlwnmr9,r4,r6,30,31\n\
1795 rlwnmr10,r4,r7,30,31\n\
1796 addr3,r8,r9\n\
1797 addr3,r3,r10\n\
1798 */\n\
1799 }\n\
1800 \n\
1801 \n\
1802 function TimeFunc(func) {\n\
1803 var x, y, t;\n\
1804 var sum = 0;\n\
1805 for(var x=0; x<500; x++)\n\
1806 for(var y=0; y<256; y++) sum += func(y);\n\
1807 return sum;\n\
1808 }\n\
1809 \n\
1810 sum = TimeFunc(fast3bitlookup);\n\
1811 \n\
1812 var expected = 512000;\n\
1813 if (sum != expected)\n\
1814     throw \"ERROR: bad result: expected \" + expected + \" but got \" + sum;\n\
1815 \n\
1816 \n\
1817 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1818 \n\
1819 record(_sunSpiderInterval);\n\
1820 </script>\n\
1821 \n\
1822 \n\
1823 </body>\n\
1824 </html>\n\
1825 ", "<!DOCTYPE html>\n\
1826 <head>\n\
1827 \n\
1828 <meta charset=utf8>\n\
1829 \n\
1830 <!--\n\
1831  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1832 \n\
1833  Redistribution and use in source and binary forms, with or without\n\
1834  modification, are permitted provided that the following conditions\n\
1835  are met:\n\
1836  1. Redistributions of source code must retain the above copyright\n\
1837     notice, this list of conditions and the following disclaimer.\n\
1838  2. Redistributions in binary form must reproduce the above copyright\n\
1839     notice, this list of conditions and the following disclaimer in the\n\
1840     documentation and/or other materials provided with the distribution.\n\
1841 \n\
1842  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1843  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1844  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1845  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1846  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1847  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1848  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1849  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1850  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1851  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1852  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1853 -->\n\
1854 \n\
1855 <title>SunSpider bitops-bits-in-byte</title>\n\
1856 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1857 <style>\n\
1858 #countdown {\n\
1859     font-size: 128px; \n\
1860     text-align: center;\n\
1861 }\n\
1862 </style>\n\
1863 </head>\n\
1864 \n\
1865 <body>\n\
1866 <h3 id=\"countdown\"></h3>\n\
1867 <script>\n\
1868 if (window.parent) {\n\
1869     document.getElementById(\"countdown\").innerHTML =\n\
1870         window.parent.currentRepeat < 0\n\
1871             ? \"warmup\"\n\
1872             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
1873 }\n\
1874 \n\
1875 function record(time) {\n\
1876     if (window.parent)\n\
1877         parent.recordResult(time);\n\
1878 }\n\
1879 \n\
1880 window.onerror = function(e) {\n\
1881     console.log(\"bitops-bits-in-byte failed with error: \" + e);\n\
1882     record(0 / 0);\n\
1883 }\n\
1884 \n\
1885 var _sunSpiderStartDate = new Date();\n\
1886 \n\
1887 // Copyright (c) 2004 by Arthur Langereis (arthur_ext at domain xfinitegames, tld com)\n\
1888 \n\
1889 \n\
1890 var result = 0;\n\
1891 \n\
1892 // 1 op = 2 assigns, 16 compare/branches, 8 ANDs, (0-8) ADDs, 8 SHLs\n\
1893 // O(n)\n\
1894 function bitsinbyte(b) {\n\
1895 var m = 1, c = 0;\n\
1896 while(m<0x100) {\n\
1897 if(b & m) c++;\n\
1898 m <<= 1;\n\
1899 }\n\
1900 return c;\n\
1901 }\n\
1902 \n\
1903 function TimeFunc(func) {\n\
1904 var x, y, t;\n\
1905 var sum = 0;\n\
1906 for(var x=0; x<350; x++)\n\
1907 for(var y=0; y<256; y++) sum += func(y);\n\
1908 return sum;\n\
1909 }\n\
1910 \n\
1911 result = TimeFunc(bitsinbyte);\n\
1912 \n\
1913 var expected = 358400;\n\
1914 if (result != expected)\n\
1915     throw \"ERROR: bad result: expected \" + expected + \" but got \" + result;\n\
1916 \n\
1917 \n\
1918 \n\
1919 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1920 \n\
1921 record(_sunSpiderInterval);\n\
1922 </script>\n\
1923 \n\
1924 \n\
1925 </body>\n\
1926 </html>\n\
1927 ", "<!DOCTYPE html>\n\
1928 <head>\n\
1929 \n\
1930 <meta charset=utf8>\n\
1931 \n\
1932 <!--\n\
1933  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1934 \n\
1935  Redistribution and use in source and binary forms, with or without\n\
1936  modification, are permitted provided that the following conditions\n\
1937  are met:\n\
1938  1. Redistributions of source code must retain the above copyright\n\
1939     notice, this list of conditions and the following disclaimer.\n\
1940  2. Redistributions in binary form must reproduce the above copyright\n\
1941     notice, this list of conditions and the following disclaimer in the\n\
1942     documentation and/or other materials provided with the distribution.\n\
1943 \n\
1944  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1945  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1946  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1947  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1948  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1949  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1950  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1951  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1952  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1953  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1954  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1955 -->\n\
1956 \n\
1957 <title>SunSpider bitops-bitwise-and</title>\n\
1958 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1959 <style>\n\
1960 #countdown {\n\
1961     font-size: 128px; \n\
1962     text-align: center;\n\
1963 }\n\
1964 </style>\n\
1965 </head>\n\
1966 \n\
1967 <body>\n\
1968 <h3 id=\"countdown\"></h3>\n\
1969 <script>\n\
1970 if (window.parent) {\n\
1971     document.getElementById(\"countdown\").innerHTML =\n\
1972         window.parent.currentRepeat < 0\n\
1973             ? \"warmup\"\n\
1974             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
1975 }\n\
1976 \n\
1977 function record(time) {\n\
1978     if (window.parent)\n\
1979         parent.recordResult(time);\n\
1980 }\n\
1981 \n\
1982 window.onerror = function(e) {\n\
1983     console.log(\"bitops-bitwise-and failed with error: \" + e);\n\
1984     record(0 / 0);\n\
1985 }\n\
1986 \n\
1987 var _sunSpiderStartDate = new Date();\n\
1988 \n\
1989 /*\n\
1990  * Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1991  *\n\
1992  * Redistribution and use in source and binary forms, with or without\n\
1993  * modification, are permitted provided that the following conditions\n\
1994  * are met:\n\
1995  * 1. Redistributions of source code must retain the above copyright\n\
1996  *    notice, this list of conditions and the following disclaimer.\n\
1997  * 2. Redistributions in binary form must reproduce the above copyright\n\
1998  *    notice, this list of conditions and the following disclaimer in the\n\
1999  *    documentation and/or other materials provided with the distribution.\n\
2000  *\n\
2001  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
2002  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
2003  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
2004  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
2005  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
2006  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
2007  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
2008  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
2009  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
2010  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
2011  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
2012  */\n\
2013 \n\
2014 bitwiseAndValue = 4294967296;\n\
2015 for (var i = 0; i < 600000; i++)\n\
2016     bitwiseAndValue = bitwiseAndValue & i;\n\
2017 \n\
2018 var result = bitwiseAndValue;\n\
2019 \n\
2020 var expected = 0;\n\
2021 if (result != expected)\n\
2022     throw \"ERROR: bad result: expected \" + expected + \" but got \" + result;\n\
2023 \n\
2024 \n\
2025 \n\
2026 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
2027 \n\
2028 record(_sunSpiderInterval);\n\
2029 </script>\n\
2030 \n\
2031 \n\
2032 </body>\n\
2033 </html>\n\
2034 ", "<!DOCTYPE html>\n\
2035 <head>\n\
2036 \n\
2037 <meta charset=utf8>\n\
2038 \n\
2039 <!--\n\
2040  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
2041 \n\
2042  Redistribution and use in source and binary forms, with or without\n\
2043  modification, are permitted provided that the following conditions\n\
2044  are met:\n\
2045  1. Redistributions of source code must retain the above copyright\n\
2046     notice, this list of conditions and the following disclaimer.\n\
2047  2. Redistributions in binary form must reproduce the above copyright\n\
2048     notice, this list of conditions and the following disclaimer in the\n\
2049     documentation and/or other materials provided with the distribution.\n\
2050 \n\
2051  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
2052  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
2053  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
2054  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
2055  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
2056  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
2057  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
2058  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
2059  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
2060  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
2061  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
2062 -->\n\
2063 \n\
2064 <title>SunSpider bitops-nsieve-bits</title>\n\
2065 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
2066 <style>\n\
2067 #countdown {\n\
2068     font-size: 128px; \n\
2069     text-align: center;\n\
2070 }\n\
2071 </style>\n\
2072 </head>\n\
2073 \n\
2074 <body>\n\
2075 <h3 id=\"countdown\"></h3>\n\
2076 <script>\n\
2077 if (window.parent) {\n\
2078     document.getElementById(\"countdown\").innerHTML =\n\
2079         window.parent.currentRepeat < 0\n\
2080             ? \"warmup\"\n\
2081             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
2082 }\n\
2083 \n\
2084 function record(time) {\n\
2085     if (window.parent)\n\
2086         parent.recordResult(time);\n\
2087 }\n\
2088 \n\
2089 window.onerror = function(e) {\n\
2090     console.log(\"bitops-nsieve-bits failed with error: \" + e);\n\
2091     record(0 / 0);\n\
2092 }\n\
2093 \n\
2094 var _sunSpiderStartDate = new Date();\n\
2095 \n\
2096 // The Great Computer Language Shootout\n\
2097 //  http://shootout.alioth.debian.org\n\
2098 //\n\
2099 //  Contributed by Ian Osgood\n\
2100 \n\
2101 function pad(n,width) {\n\
2102   var s = n.toString();\n\
2103   while (s.length < width) s = ' ' + s;\n\
2104   return s;\n\
2105 }\n\
2106 \n\
2107 function primes(isPrime, n) {\n\
2108   var i, count = 0, m = 10000<<n, size = m+31>>5;\n\
2109 \n\
2110   for (i=0; i<size; i++) isPrime[i] = 0xffffffff;\n\
2111 \n\
2112   for (i=2; i<m; i++)\n\
2113     if (isPrime[i>>5] & 1<<(i&31)) {\n\
2114       for (var j=i+i; j<m; j+=i)\n\
2115         isPrime[j>>5] &= ~(1<<(j&31));\n\
2116       count++;\n\
2117     }\n\
2118 }\n\
2119 \n\
2120 function sieve() {\n\
2121     for (var i = 4; i <= 4; i++) {\n\
2122         var isPrime = new Array((10000<<i)+31>>5);\n\
2123         primes(isPrime, i);\n\
2124     }\n\
2125     return isPrime;\n\
2126 }\n\
2127 \n\
2128 var result = sieve();\n\
2129 \n\
2130 var sum = 0;\n\
2131 for (var i = 0; i < result.length; ++i)\n\
2132     sum += result[i];\n\
2133 \n\
2134 var expected = -1286749544853;\n\
2135 if (sum != expected)\n\
2136     throw \"ERROR: bad result: expected \" + expected + \" but got \" + sum;\n\
2137 \n\
2138 \n\
2139 \n\
2140 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
2141 \n\
2142 record(_sunSpiderInterval);\n\
2143 </script>\n\
2144 \n\
2145 \n\
2146 </body>\n\
2147 </html>\n\
2148 ", "<!DOCTYPE html>\n\
2149 <head>\n\
2150 \n\
2151 <meta charset=utf8>\n\
2152 \n\
2153 <!--\n\
2154  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
2155 \n\
2156  Redistribution and use in source and binary forms, with or without\n\
2157  modification, are permitted provided that the following conditions\n\
2158  are met:\n\
2159  1. Redistributions of source code must retain the above copyright\n\
2160     notice, this list of conditions and the following disclaimer.\n\
2161  2. Redistributions in binary form must reproduce the above copyright\n\
2162     notice, this list of conditions and the following disclaimer in the\n\
2163     documentation and/or other materials provided with the distribution.\n\
2164 \n\
2165  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
2166  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
2167  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
2168  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
2169  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
2170  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
2171  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
2172  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
2173  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
2174  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
2175  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
2176 -->\n\
2177 \n\
2178 <title>SunSpider controlflow-recursive</title>\n\
2179 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
2180 <style>\n\
2181 #countdown {\n\
2182     font-size: 128px; \n\
2183     text-align: center;\n\
2184 }\n\
2185 </style>\n\
2186 </head>\n\
2187 \n\
2188 <body>\n\
2189 <h3 id=\"countdown\"></h3>\n\
2190 <script>\n\
2191 if (window.parent) {\n\
2192     document.getElementById(\"countdown\").innerHTML =\n\
2193         window.parent.currentRepeat < 0\n\
2194             ? \"warmup\"\n\
2195             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
2196 }\n\
2197 \n\
2198 function record(time) {\n\
2199     if (window.parent)\n\
2200         parent.recordResult(time);\n\
2201 }\n\
2202 \n\
2203 window.onerror = function(e) {\n\
2204     console.log(\"controlflow-recursive failed with error: \" + e);\n\
2205     record(0 / 0);\n\
2206 }\n\
2207 \n\
2208 var _sunSpiderStartDate = new Date();\n\
2209 \n\
2210 // The Computer Language Shootout\n\
2211 // http://shootout.alioth.debian.org/\n\
2212 // contributed by Isaac Gouy\n\
2213 \n\
2214 function ack(m,n){\n\
2215    if (m==0) { return n+1; }\n\
2216    if (n==0) { return ack(m-1,1); }\n\
2217    return ack(m-1, ack(m,n-1) );\n\
2218 }\n\
2219 \n\
2220 function fib(n) {\n\
2221     if (n < 2){ return 1; }\n\
2222     return fib(n-2) + fib(n-1);\n\
2223 }\n\
2224 \n\
2225 function tak(x,y,z) {\n\
2226     if (y >= x) return z;\n\
2227     return tak(tak(x-1,y,z), tak(y-1,z,x), tak(z-1,x,y));\n\
2228 }\n\
2229 \n\
2230 var result = 0;\n\
2231 \n\
2232 for ( var i = 3; i <= 5; i++ ) {\n\
2233     result += ack(3,i);\n\
2234     result += fib(17.0+i);\n\
2235     result += tak(3*i+3,2*i+2,i+1);\n\
2236 }\n\
2237 \n\
2238 var expected = 57775;\n\
2239 if (result != expected)\n\
2240     throw \"ERROR: bad result: expected \" + expected + \" but got \" + result;\n\
2241 \n\
2242 \n\
2243 \n\
2244 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
2245 \n\
2246 record(_sunSpiderInterval);\n\
2247 </script>\n\
2248 \n\
2249 \n\
2250 </body>\n\
2251 </html>\n\
2252 ", "<!DOCTYPE html>\n\
2253 <head>\n\
2254 \n\
2255 <meta charset=utf8>\n\
2256 \n\
2257 <!--\n\
2258  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
2259 \n\
2260  Redistribution and use in source and binary forms, with or without\n\
2261  modification, are permitted provided that the following conditions\n\
2262  are met:\n\
2263  1. Redistributions of source code must retain the above copyright\n\
2264     notice, this list of conditions and the following disclaimer.\n\
2265  2. Redistributions in binary form must reproduce the above copyright\n\
2266     notice, this list of conditions and the following disclaimer in the\n\
2267     documentation and/or other materials provided with the distribution.\n\
2268 \n\
2269  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
2270  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
2271  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
2272  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
2273  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
2274  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
2275  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
2276  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
2277  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
2278  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
2279  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
2280 -->\n\
2281 \n\
2282 <title>SunSpider crypto-aes</title>\n\
2283 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
2284 <style>\n\
2285 #countdown {\n\
2286     font-size: 128px; \n\
2287     text-align: center;\n\
2288 }\n\
2289 </style>\n\
2290 </head>\n\
2291 \n\
2292 <body>\n\
2293 <h3 id=\"countdown\"></h3>\n\
2294 <script>\n\
2295 if (window.parent) {\n\
2296     document.getElementById(\"countdown\").innerHTML =\n\
2297         window.parent.currentRepeat < 0\n\
2298             ? \"warmup\"\n\
2299             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
2300 }\n\
2301 \n\
2302 function record(time) {\n\
2303     if (window.parent)\n\
2304         parent.recordResult(time);\n\
2305 }\n\
2306 \n\
2307 window.onerror = function(e) {\n\
2308     console.log(\"crypto-aes failed with error: \" + e);\n\
2309     record(0 / 0);\n\
2310 }\n\
2311 \n\
2312 var _sunSpiderStartDate = new Date();\n\
2313 \n\
2314 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n\
2315 \n\
2316 /*\n\
2317  * AES Cipher function: encrypt 'input' with Rijndael algorithm\n\
2318  *\n\
2319  *   takes   byte-array 'input' (16 bytes)\n\
2320  *           2D byte-array key schedule 'w' (Nr+1 x Nb bytes)\n\
2321  *\n\
2322  *   applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage\n\
2323  *\n\
2324  *   returns byte-array encrypted value (16 bytes)\n\
2325  */\n\
2326 function Cipher(input, w) {    // main Cipher function [§5.1]\n\
2327   var Nb = 4;               // block size (in words): no of columns in state (fixed at 4 for AES)\n\
2328   var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys\n\
2329 \n\
2330   var state = [[],[],[],[]];  // initialise 4xNb byte-array 'state' with input [§3.4]\n\
2331   for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i];\n\
2332 \n\
2333   state = AddRoundKey(state, w, 0, Nb);\n\
2334 \n\
2335   for (var round=1; round<Nr; round++) {\n\
2336     state = SubBytes(state, Nb);\n\
2337     state = ShiftRows(state, Nb);\n\
2338     state = MixColumns(state, Nb);\n\
2339     state = AddRoundKey(state, w, round, Nb);\n\
2340   }\n\
2341 \n\
2342   state = SubBytes(state, Nb);\n\
2343   state = ShiftRows(state, Nb);\n\
2344   state = AddRoundKey(state, w, Nr, Nb);\n\
2345 \n\
2346   var output = new Array(4*Nb);  // convert state to 1-d array before returning [§3.4]\n\
2347   for (var i=0; i<4*Nb; i++) output[i] = state[i%4][Math.floor(i/4)];\n\
2348   return output;\n\
2349 }\n\
2350 \n\
2351 \n\
2352 function SubBytes(s, Nb) {    // apply SBox to state S [§5.1.1]\n\
2353   for (var r=0; r<4; r++) {\n\
2354     for (var c=0; c<Nb; c++) s[r][c] = Sbox[s[r][c]];\n\
2355   }\n\
2356   return s;\n\
2357 }\n\
2358 \n\
2359 \n\
2360 function ShiftRows(s, Nb) {    // shift row r of state S left by r bytes [§5.1.2]\n\
2361   var t = new Array(4);\n\
2362   for (var r=1; r<4; r++) {\n\
2363     for (var c=0; c<4; c++) t[c] = s[r][(c+r)%Nb];  // shift into temp copy\n\
2364     for (var c=0; c<4; c++) s[r][c] = t[c];         // and copy back\n\
2365   }          // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):\n\
2366   return s;  // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf \n\
2367 }\n\
2368 \n\
2369 \n\
2370 function MixColumns(s, Nb) {   // combine bytes of each col of state S [§5.1.3]\n\
2371   for (var c=0; c<4; c++) {\n\
2372     var a = new Array(4);  // 'a' is a copy of the current column from 's'\n\
2373     var b = new Array(4);  // 'b' is a•{02} in GF(2^8)\n\
2374     for (var i=0; i<4; i++) {\n\
2375       a[i] = s[i][c];\n\
2376       b[i] = s[i][c]&0x80 ? s[i][c]<<1 ^ 0x011b : s[i][c]<<1;\n\
2377     }\n\
2378     // a[n] ^ b[n] is a•{03} in GF(2^8)\n\
2379     s[0][c] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3]; // 2*a0 + 3*a1 + a2 + a3\n\
2380     s[1][c] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3]; // a0 * 2*a1 + 3*a2 + a3\n\
2381     s[2][c] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3]; // a0 + a1 + 2*a2 + 3*a3\n\
2382     s[3][c] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3]; // 3*a0 + a1 + a2 + 2*a3\n\
2383   }\n\
2384   return s;\n\
2385 }\n\
2386 \n\
2387 \n\
2388 function AddRoundKey(state, w, rnd, Nb) {  // xor Round Key into state S [§5.1.4]\n\
2389   for (var r=0; r<4; r++) {\n\
2390     for (var c=0; c<Nb; c++) state[r][c] ^= w[rnd*4+c][r];\n\
2391   }\n\
2392   return state;\n\
2393 }\n\
2394 \n\
2395 \n\
2396 function KeyExpansion(key) {  // generate Key Schedule (byte-array Nr+1 x Nb) from Key [§5.2]\n\
2397   var Nb = 4;            // block size (in words): no of columns in state (fixed at 4 for AES)\n\
2398   var Nk = key.length/4  // key length (in words): 4/6/8 for 128/192/256-bit keys\n\
2399   var Nr = Nk + 6;       // no of rounds: 10/12/14 for 128/192/256-bit keys\n\
2400 \n\
2401   var w = new Array(Nb*(Nr+1));\n\
2402   var temp = new Array(4);\n\
2403 \n\
2404   for (var i=0; i<Nk; i++) {\n\
2405     var r = [key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]];\n\
2406     w[i] = r;\n\
2407   }\n\
2408 \n\
2409   for (var i=Nk; i<(Nb*(Nr+1)); i++) {\n\
2410     w[i] = new Array(4);\n\
2411     for (var t=0; t<4; t++) temp[t] = w[i-1][t];\n\
2412     if (i % Nk == 0) {\n\
2413       temp = SubWord(RotWord(temp));\n\
2414       for (var t=0; t<4; t++) temp[t] ^= Rcon[i/Nk][t];\n\
2415     } else if (Nk > 6 && i%Nk == 4) {\n\
2416       temp = SubWord(temp);\n\
2417     }\n\
2418     for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t];\n\
2419   }\n\
2420 \n\
2421   return w;\n\
2422 }\n\
2423 \n\
2424 function SubWord(w) {    // apply SBox to 4-byte word w\n\
2425   for (var i=0; i<4; i++) w[i] = Sbox[w[i]];\n\
2426   return w;\n\
2427 }\n\
2428 \n\
2429 function RotWord(w) {    // rotate 4-byte word w left by one byte\n\
2430   w[4] = w[0];\n\
2431   for (var i=0; i<4; i++) w[i] = w[i+1];\n\
2432   return w;\n\
2433 }\n\
2434 \n\
2435 \n\
2436 // Sbox is pre-computed multiplicative inverse in GF(2^8) used in SubBytes and KeyExpansion [§5.1.1]\n\
2437 var Sbox =  [0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,\n\
2438              0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,\n\
2439              0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,\n\
2440              0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,\n\
2441              0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,\n\
2442              0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,\n\
2443              0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,\n\
2444              0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,\n\
2445              0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,\n\
2446              0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,\n\
2447              0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,\n\
2448              0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,\n\
2449              0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,\n\
2450              0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,\n\
2451              0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,\n\
2452              0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16];\n\
2453 \n\
2454 // Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2]\n\
2455 var Rcon = [ [0x00, 0x00, 0x00, 0x00],\n\
2456              [0x01, 0x00, 0x00, 0x00],\n\
2457              [0x02, 0x00, 0x00, 0x00],\n\
2458              [0x04, 0x00, 0x00, 0x00],\n\
2459              [0x08, 0x00, 0x00, 0x00],\n\
2460              [0x10, 0x00, 0x00, 0x00],\n\
2461              [0x20, 0x00, 0x00, 0x00],\n\
2462              [0x40, 0x00, 0x00, 0x00],\n\
2463              [0x80, 0x00, 0x00, 0x00],\n\
2464              [0x1b, 0x00, 0x00, 0x00],\n\
2465              [0x36, 0x00, 0x00, 0x00] ]; \n\
2466 \n\
2467 \n\
2468 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n\
2469 \n\
2470 /* \n\
2471  * Use AES to encrypt 'plaintext' with 'password' using 'nBits' key, in 'Counter' mode of operation\n\
2472  *                           - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf\n\
2473  *   for each block\n\
2474  *   - outputblock = cipher(counter, key)\n\
2475  *   - cipherblock = plaintext xor outputblock\n\
2476  */\n\
2477 function AESEncryptCtr(plaintext, password, nBits) {\n\
2478   if (!(nBits==128 || nBits==192 || nBits==256)) return '';  // standard allows 128/192/256 bit keys\n\
2479 \n\
2480   // for this example script, generate the key by applying Cipher to 1st 16/24/32 chars of password; \n\
2481   // for real-world applications, a more secure approach would be to hash the password e.g. with SHA-1\n\
2482   var nBytes = nBits/8;  // no bytes in key\n\
2483   var pwBytes = new Array(nBytes);\n\
2484   for (var i=0; i<nBytes; i++) pwBytes[i] = password.charCodeAt(i) & 0xff;\n\
2485   var key = Cipher(pwBytes, KeyExpansion(pwBytes));\n\
2486   key = key.concat(key.slice(0, nBytes-16));  // key is now 16/24/32 bytes long\n\
2487 \n\
2488   // initialise counter block (NIST SP800-38A §B.2): millisecond time-stamp for nonce in 1st 8 bytes,\n\
2489   // block counter in 2nd 8 bytes\n\
2490   var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES\n\
2491   var counterBlock = new Array(blockSize);  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES\n\
2492   var nonce = (new Date()).getTime();  // milliseconds since 1-Jan-1970\n\
2493 \n\
2494   // encode nonce in two stages to cater for JavaScript 32-bit limit on bitwise ops\n\
2495   for (var i=0; i<4; i++) counterBlock[i] = (nonce >>> i*8) & 0xff;\n\
2496   for (var i=0; i<4; i++) counterBlock[i+4] = (nonce/0x100000000 >>> i*8) & 0xff; \n\
2497 \n\
2498   // generate key schedule - an expansion of the key into distinct Key Rounds for each round\n\
2499   var keySchedule = KeyExpansion(key);\n\
2500 \n\
2501   var blockCount = Math.ceil(plaintext.length/blockSize);\n\
2502   var ciphertext = new Array(blockCount);  // ciphertext as array of strings\n\
2503   \n\
2504   for (var b=0; b<blockCount; b++) {\n\
2505     // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)\n\
2506     // again done in two stages for 32-bit ops\n\
2507     for (var c=0; c<4; c++) counterBlock[15-c] = (b >>> c*8) & 0xff;\n\
2508     for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8)\n\
2509 \n\
2510     var cipherCntr = Cipher(counterBlock, keySchedule);  // -- encrypt counter block --\n\
2511     \n\
2512     // calculate length of final block:\n\
2513     var blockLength = b<blockCount-1 ? blockSize : (plaintext.length-1)%blockSize+1;\n\
2514 \n\
2515     var ct = '';\n\
2516     for (var i=0; i<blockLength; i++) {  // -- xor plaintext with ciphered counter byte-by-byte --\n\
2517       var plaintextByte = plaintext.charCodeAt(b*blockSize+i);\n\
2518       var cipherByte = plaintextByte ^ cipherCntr[i];\n\
2519       ct += String.fromCharCode(cipherByte);\n\
2520     }\n\
2521     // ct is now ciphertext for this block\n\
2522 \n\
2523     ciphertext[b] = escCtrlChars(ct);  // escape troublesome characters in ciphertext\n\
2524   }\n\
2525 \n\
2526   // convert the nonce to a string to go on the front of the ciphertext\n\
2527   var ctrTxt = '';\n\
2528   for (var i=0; i<8; i++) ctrTxt += String.fromCharCode(counterBlock[i]);\n\
2529   ctrTxt = escCtrlChars(ctrTxt);\n\
2530 \n\
2531   // use '-' to separate blocks, use Array.join to concatenate arrays of strings for efficiency\n\
2532   return ctrTxt + '-' + ciphertext.join('-');\n\
2533 }\n\
2534 \n\
2535 \n\
2536 /* \n\
2537  * Use AES to decrypt 'ciphertext' with 'password' using 'nBits' key, in Counter mode of operation\n\
2538  *\n\
2539  *   for each block\n\
2540  *   - outputblock = cipher(counter, key)\n\
2541  *   - cipherblock = plaintext xor outputblock\n\
2542  */\n\
2543 function AESDecryptCtr(ciphertext, password, nBits) {\n\
2544   if (!(nBits==128 || nBits==192 || nBits==256)) return '';  // standard allows 128/192/256 bit keys\n\
2545 \n\
2546   var nBytes = nBits/8;  // no bytes in key\n\
2547   var pwBytes = new Array(nBytes);\n\
2548   for (var i=0; i<nBytes; i++) pwBytes[i] = password.charCodeAt(i) & 0xff;\n\
2549   var pwKeySchedule = KeyExpansion(pwBytes);\n\
2550   var key = Cipher(pwBytes, pwKeySchedule);\n\
2551   key = key.concat(key.slice(0, nBytes-16));  // key is now 16/24/32 bytes long\n\
2552 \n\
2553   var keySchedule = KeyExpansion(key);\n\
2554 \n\
2555   ciphertext = ciphertext.split('-');  // split ciphertext into array of block-length strings \n\
2556 \n\
2557   // recover nonce from 1st element of ciphertext\n\
2558   var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES\n\
2559   var counterBlock = new Array(blockSize);\n\
2560   var ctrTxt = unescCtrlChars(ciphertext[0]);\n\
2561   for (var i=0; i<8; i++) counterBlock[i] = ctrTxt.charCodeAt(i);\n\
2562 \n\
2563   var plaintext = new Array(ciphertext.length-1);\n\
2564 \n\
2565   for (var b=1; b<ciphertext.length; b++) {\n\
2566     // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)\n\
2567     for (var c=0; c<4; c++) counterBlock[15-c] = ((b-1) >>> c*8) & 0xff;\n\
2568     for (var c=0; c<4; c++) counterBlock[15-c-4] = ((b/0x100000000-1) >>> c*8) & 0xff;\n\
2569 \n\
2570     var cipherCntr = Cipher(counterBlock, keySchedule);  // encrypt counter block\n\
2571 \n\
2572     ciphertext[b] = unescCtrlChars(ciphertext[b]);\n\
2573 \n\
2574     var pt = '';\n\
2575     for (var i=0; i<ciphertext[b].length; i++) {\n\
2576       // -- xor plaintext with ciphered counter byte-by-byte --\n\
2577       var ciphertextByte = ciphertext[b].charCodeAt(i);\n\
2578       var plaintextByte = ciphertextByte ^ cipherCntr[i];\n\
2579       pt += String.fromCharCode(plaintextByte);\n\
2580     }\n\
2581     // pt is now plaintext for this block\n\
2582 \n\
2583     plaintext[b-1] = pt;  // b-1 'cos no initial nonce block in plaintext\n\
2584   }\n\
2585 \n\
2586   return plaintext.join('');\n\
2587 }\n\
2588 \n\
2589 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n\
2590 \n\
2591 function escCtrlChars(str) {  // escape control chars which might cause problems handling ciphertext\n\
2592   return str.replace(/[\\0\\t\\n\\v\\f\\r\\xa0'\"!-]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });\n\
2593 }  // \\xa0 to cater for bug in Firefox; include '-' to leave it free for use as a block marker\n\
2594 \n\
2595 function unescCtrlChars(str) {  // unescape potentially problematic control characters\n\
2596   return str.replace(/!\\d\\d?\\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });\n\
2597 }\n\
2598 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n\
2599 \n\
2600 /*\n\
2601  * if escCtrlChars()/unescCtrlChars() still gives problems, use encodeBase64()/decodeBase64() instead\n\
2602  */\n\
2603 var b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\n\
2604 \n\
2605 function encodeBase64(str) {  // http://tools.ietf.org/html/rfc4648\n\
2606    var o1, o2, o3, h1, h2, h3, h4, bits, i=0, enc='';\n\
2607    \n\
2608    str = encodeUTF8(str);  // encode multi-byte chars into UTF-8 for byte-array\n\
2609 \n\
2610    do {  // pack three octets into four hexets\n\
2611       o1 = str.charCodeAt(i++);\n\
2612       o2 = str.charCodeAt(i++);\n\
2613       o3 = str.charCodeAt(i++);\n\
2614       \n\
2615       bits = o1<<16 | o2<<8 | o3;\n\
2616       \n\
2617       h1 = bits>>18 & 0x3f;\n\
2618       h2 = bits>>12 & 0x3f;\n\
2619       h3 = bits>>6 & 0x3f;\n\
2620       h4 = bits & 0x3f;\n\
2621       \n\
2622       // end of string? index to '=' in b64\n\
2623       if (isNaN(o3)) h4 = 64;\n\
2624       if (isNaN(o2)) h3 = 64;\n\
2625       \n\
2626       // use hexets to index into b64, and append result to encoded string\n\
2627       enc += b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);\n\
2628    } while (i < str.length);\n\
2629    \n\
2630    return enc;\n\
2631 }\n\
2632 \n\
2633 function decodeBase64(str) {\n\
2634    var o1, o2, o3, h1, h2, h3, h4, bits, i=0, enc='';\n\
2635 \n\
2636    do {  // unpack four hexets into three octets using index points in b64\n\
2637       h1 = b64.indexOf(str.charAt(i++));\n\
2638       h2 = b64.indexOf(str.charAt(i++));\n\
2639       h3 = b64.indexOf(str.charAt(i++));\n\
2640       h4 = b64.indexOf(str.charAt(i++));\n\
2641       \n\
2642       bits = h1<<18 | h2<<12 | h3<<6 | h4;\n\
2643       \n\
2644       o1 = bits>>16 & 0xff;\n\
2645       o2 = bits>>8 & 0xff;\n\
2646       o3 = bits & 0xff;\n\
2647       \n\
2648       if (h3 == 64)      enc += String.fromCharCode(o1);\n\
2649       else if (h4 == 64) enc += String.fromCharCode(o1, o2);\n\
2650       else               enc += String.fromCharCode(o1, o2, o3);\n\
2651    } while (i < str.length);\n\
2652 \n\
2653    return decodeUTF8(enc);  // decode UTF-8 byte-array back to Unicode\n\
2654 }\n\
2655 \n\
2656 function encodeUTF8(str) {  // encode multi-byte string into utf-8 multiple single-byte characters \n\
2657   str = str.replace(\n\
2658       /[\\u0080-\\u07ff]/g,  // U+0080 - U+07FF = 2-byte chars\n\
2659       function(c) { \n\
2660         var cc = c.charCodeAt(0);\n\
2661         return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); }\n\
2662     );\n\
2663   str = str.replace(\n\
2664       /[\\u0800-\\uffff]/g,  // U+0800 - U+FFFF = 3-byte chars\n\
2665       function(c) { \n\
2666         var cc = c.charCodeAt(0); \n\
2667         return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); }\n\
2668     );\n\
2669   return str;\n\
2670 }\n\
2671 \n\
2672 function decodeUTF8(str) {  // decode utf-8 encoded string back into multi-byte characters\n\
2673   str = str.replace(\n\
2674       /[\\u00c0-\\u00df][\\u0080-\\u00bf]/g,                 // 2-byte chars\n\
2675       function(c) { \n\
2676         var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f;\n\
2677         return String.fromCharCode(cc); }\n\
2678     );\n\
2679   str = str.replace(\n\
2680       /[\\u00e0-\\u00ef][\\u0080-\\u00bf][\\u0080-\\u00bf]/g,  // 3-byte chars\n\
2681       function(c) { \n\
2682         var cc = (c.charCodeAt(0)&0x0f)<<12 | (c.charCodeAt(1)&0x3f<<6) | c.charCodeAt(2)&0x3f; \n\
2683         return String.fromCharCode(cc); }\n\
2684     );\n\
2685   return str;\n\
2686 }\n\
2687 \n\
2688 \n\
2689 function byteArrayToHexStr(b) {  // convert byte array to hex string for displaying test vectors\n\
2690   var s = '';\n\
2691   for (var i=0; i<b.length; i++) s += b[i].toString(16) + ' ';\n\
2692   return s;\n\
2693 }\n\
2694 \n\
2695 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n\
2696 \n\
2697 \n\
2698 var plainText = \"ROMEO: But, soft! what light through yonder window breaks?\\n\\\n\
2699 It is the east, and Juliet is the sun.\\n\\\n\
2700 Arise, fair sun, and kill the envious moon,\\n\\\n\
2701 Who is already sick and pale with grief,\\n\\\n\
2702 That thou her maid art far more fair than she:\\n\\\n\
2703 Be not her maid, since she is envious;\\n\\\n\
2704 Her vestal livery is but sick and green\\n\\\n\
2705 And none but fools do wear it; cast it off.\\n\\\n\
2706 It is my lady, O, it is my love!\\n\\\n\
2707 O, that she knew she were!\\n\\\n\
2708 She speaks yet she says nothing: what of that?\\n\\\n\
2709 Her eye discourses; I will answer it.\\n\\\n\
2710 I am too bold, 'tis not to me she speaks:\\n\\\n\
2711 Two of the fairest stars in all the heaven,\\n\\\n\
2712 Having some business, do entreat her eyes\\n\\\n\
2713 To twinkle in their spheres till they return.\\n\\\n\
2714 What if her eyes were there, they in her head?\\n\\\n\
2715 The brightness of her cheek would shame those stars,\\n\\\n\
2716 As daylight doth a lamp; her eyes in heaven\\n\\\n\
2717 Would through the airy region stream so bright\\n\\\n\
2718 That birds would sing and think it were not night.\\n\\\n\
2719 See, how she leans her cheek upon her hand!\\n\\\n\
2720 O, that I were a glove upon that hand,\\n\\\n\
2721 That I might touch that cheek!\\n\\\n\
2722 JULIET: Ay me!\\n\\\n\
2723 ROMEO: She speaks:\\n\\\n\
2724 O, speak again, bright angel! for thou art\\n\\\n\
2725 As glorious to this night, being o'er my head\\n\\\n\
2726 As is a winged messenger of heaven\\n\\\n\
2727 Unto the white-upturned wondering eyes\\n\\\n\
2728 Of mortals that fall back to gaze on him\\n\\\n\
2729 When he bestrides the lazy-pacing clouds\\n\\\n\
2730 And sails upon the bosom of the air.\";\n\
2731 \n\
2732 var password = \"O Romeo, Romeo! wherefore art thou Romeo?\";\n\
2733 \n\
2734 var cipherText = AESEncryptCtr(plainText, password, 256);\n\
2735 var decryptedText = AESDecryptCtr(cipherText, password, 256);\n\
2736 \n\
2737 if (decryptedText != plainText)\n\
2738     throw \"ERROR: bad result: expected \" + plainText + \" but got \" + decryptedText;\n\
2739 \n\
2740 \n\
2741 \n\
2742 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
2743 \n\
2744 record(_sunSpiderInterval);\n\
2745 </script>\n\
2746 \n\
2747 \n\
2748 </body>\n\
2749 </html>\n\
2750 ", "<!DOCTYPE html>\n\
2751 <head>\n\
2752 \n\
2753 <meta charset=utf8>\n\
2754 \n\
2755 <!--\n\
2756  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
2757 \n\
2758  Redistribution and use in source and binary forms, with or without\n\
2759  modification, are permitted provided that the following conditions\n\
2760  are met:\n\
2761  1. Redistributions of source code must retain the above copyright\n\
2762     notice, this list of conditions and the following disclaimer.\n\
2763  2. Redistributions in binary form must reproduce the above copyright\n\
2764     notice, this list of conditions and the following disclaimer in the\n\
2765     documentation and/or other materials provided with the distribution.\n\
2766 \n\
2767  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
2768  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
2769  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
2770  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
2771  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
2772  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
2773  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
2774  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
2775  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
2776  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
2777  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
2778 -->\n\
2779 \n\
2780 <title>SunSpider crypto-md5</title>\n\
2781 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
2782 <style>\n\
2783 #countdown {\n\
2784     font-size: 128px; \n\
2785     text-align: center;\n\
2786 }\n\
2787 </style>\n\
2788 </head>\n\
2789 \n\
2790 <body>\n\
2791 <h3 id=\"countdown\"></h3>\n\
2792 <script>\n\
2793 if (window.parent) {\n\
2794     document.getElementById(\"countdown\").innerHTML =\n\
2795         window.parent.currentRepeat < 0\n\
2796             ? \"warmup\"\n\
2797             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
2798 }\n\
2799 \n\
2800 function record(time) {\n\
2801     if (window.parent)\n\
2802         parent.recordResult(time);\n\
2803 }\n\
2804 \n\
2805 window.onerror = function(e) {\n\
2806     console.log(\"crypto-md5 failed with error: \" + e);\n\
2807     record(0 / 0);\n\
2808 }\n\
2809 \n\
2810 var _sunSpiderStartDate = new Date();\n\
2811 \n\
2812 /*\n\
2813  * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message\n\
2814  * Digest Algorithm, as defined in RFC 1321.\n\
2815  * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.\n\
2816  * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n\
2817  * Distributed under the BSD License\n\
2818  * See http://pajhome.org.uk/crypt/md5 for more info.\n\
2819  */\n\
2820 \n\
2821 /*\n\
2822  * Configurable variables. You may need to tweak these to be compatible with\n\
2823  * the server-side, but the defaults work in most cases.\n\
2824  */\n\
2825 var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */\n\
2826 var b64pad  = \"\"; /* base-64 pad character. \"=\" for strict RFC compliance   */\n\
2827 var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */\n\
2828 \n\
2829 /*\n\
2830  * These are the functions you'll usually want to call\n\
2831  * They take string arguments and return either hex or base-64 encoded strings\n\
2832  */\n\
2833 function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}\n\
2834 function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}\n\
2835 function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}\n\
2836 function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }\n\
2837 function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }\n\
2838 function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }\n\
2839 \n\
2840 /*\n\
2841  * Perform a simple self-test to see if the VM is working\n\
2842  */\n\
2843 function md5_vm_test()\n\
2844 {\n\
2845   return hex_md5(\"abc\") == \"900150983cd24fb0d6963f7d28e17f72\";\n\
2846 }\n\
2847 \n\
2848 /*\n\
2849  * Calculate the MD5 of an array of little-endian words, and a bit length\n\
2850  */\n\
2851 function core_md5(x, len)\n\
2852 {\n\
2853   /* append padding */\n\
2854   x[len >> 5] |= 0x80 << ((len) % 32);\n\
2855   x[(((len + 64) >>> 9) << 4) + 14] = len;\n\
2856 \n\
2857   var a =  1732584193;\n\
2858   var b = -271733879;\n\
2859   var c = -1732584194;\n\
2860   var d =  271733878;\n\
2861 \n\
2862   for(var i = 0; i < x.length; i += 16)\n\
2863   {\n\
2864     var olda = a;\n\
2865     var oldb = b;\n\
2866     var oldc = c;\n\
2867     var oldd = d;\n\
2868 \n\
2869     a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);\n\
2870     d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);\n\
2871     c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);\n\
2872     b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);\n\
2873     a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);\n\
2874     d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);\n\
2875     c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);\n\
2876     b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);\n\
2877     a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);\n\
2878     d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);\n\
2879     c = md5_ff(c, d, a, b, x[i+10], 17, -42063);\n\
2880     b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);\n\
2881     a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);\n\
2882     d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);\n\
2883     c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);\n\
2884     b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);\n\
2885 \n\
2886     a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);\n\
2887     d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);\n\
2888     c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);\n\
2889     b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);\n\
2890     a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);\n\
2891     d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);\n\
2892     c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);\n\
2893     b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);\n\
2894     a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);\n\
2895     d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);\n\
2896     c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);\n\
2897     b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);\n\
2898     a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);\n\
2899     d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);\n\
2900     c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);\n\
2901     b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);\n\
2902 \n\
2903     a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);\n\
2904     d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);\n\
2905     c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);\n\
2906     b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);\n\
2907     a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);\n\
2908     d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);\n\
2909     c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);\n\
2910     b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);\n\
2911     a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);\n\
2912     d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);\n\
2913     c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);\n\
2914     b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);\n\
2915     a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);\n\
2916     d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);\n\
2917     c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);\n\
2918     b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);\n\
2919 \n\
2920     a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);\n\
2921     d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);\n\
2922     c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);\n\
2923     b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);\n\
2924     a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);\n\
2925     d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);\n\
2926     c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);\n\
2927     b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);\n\
2928     a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);\n\
2929     d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);\n\
2930     c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);\n\
2931     b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);\n\
2932     a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);\n\
2933     d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);\n\
2934     c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);\n\
2935     b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);\n\
2936 \n\
2937     a = safe_add(a, olda);\n\
2938     b = safe_add(b, oldb);\n\
2939     c = safe_add(c, oldc);\n\
2940     d = safe_add(d, oldd);\n\
2941   }\n\
2942   return Array(a, b, c, d);\n\
2943 \n\
2944 }\n\
2945 \n\
2946 /*\n\
2947  * These functions implement the four basic operations the algorithm uses.\n\
2948  */\n\
2949 function md5_cmn(q, a, b, x, s, t)\n\
2950 {\n\
2951   return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);\n\
2952 }\n\
2953 function md5_ff(a, b, c, d, x, s, t)\n\
2954 {\n\
2955   return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);\n\
2956 }\n\
2957 function md5_gg(a, b, c, d, x, s, t)\n\
2958 {\n\
2959   return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);\n\
2960 }\n\
2961 function md5_hh(a, b, c, d, x, s, t)\n\
2962 {\n\
2963   return md5_cmn(b ^ c ^ d, a, b, x, s, t);\n\
2964 }\n\
2965 function md5_ii(a, b, c, d, x, s, t)\n\
2966 {\n\
2967   return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);\n\
2968 }\n\
2969 \n\
2970 /*\n\
2971  * Calculate the HMAC-MD5, of a key and some data\n\
2972  */\n\
2973 function core_hmac_md5(key, data)\n\
2974 {\n\
2975   var bkey = str2binl(key);\n\
2976   if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);\n\
2977 \n\
2978   var ipad = Array(16), opad = Array(16);\n\
2979   for(var i = 0; i < 16; i++)\n\
2980   {\n\
2981     ipad[i] = bkey[i] ^ 0x36363636;\n\
2982     opad[i] = bkey[i] ^ 0x5C5C5C5C;\n\
2983   }\n\
2984 \n\
2985   var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);\n\
2986   return core_md5(opad.concat(hash), 512 + 128);\n\
2987 }\n\
2988 \n\
2989 /*\n\
2990  * Add integers, wrapping at 2^32. This uses 16-bit operations internally\n\
2991  * to work around bugs in some JS interpreters.\n\
2992  */\n\
2993 function safe_add(x, y)\n\
2994 {\n\
2995   var lsw = (x & 0xFFFF) + (y & 0xFFFF);\n\
2996   var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n\
2997   return (msw << 16) | (lsw & 0xFFFF);\n\
2998 }\n\
2999 \n\
3000 /*\n\
3001  * Bitwise rotate a 32-bit number to the left.\n\
3002  */\n\
3003 function bit_rol(num, cnt)\n\
3004 {\n\
3005   return (num << cnt) | (num >>> (32 - cnt));\n\
3006 }\n\
3007 \n\
3008 /*\n\
3009  * Convert a string to an array of little-endian words\n\
3010  * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.\n\
3011  */\n\
3012 function str2binl(str)\n\
3013 {\n\
3014   var bin = Array();\n\
3015   var mask = (1 << chrsz) - 1;\n\
3016   for(var i = 0; i < str.length * chrsz; i += chrsz)\n\
3017     bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);\n\
3018   return bin;\n\
3019 }\n\
3020 \n\
3021 /*\n\
3022  * Convert an array of little-endian words to a string\n\
3023  */\n\
3024 function binl2str(bin)\n\
3025 {\n\
3026   var str = \"\";\n\
3027   var mask = (1 << chrsz) - 1;\n\
3028   for(var i = 0; i < bin.length * 32; i += chrsz)\n\
3029     str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);\n\
3030   return str;\n\
3031 }\n\
3032 \n\
3033 /*\n\
3034  * Convert an array of little-endian words to a hex string.\n\
3035  */\n\
3036 function binl2hex(binarray)\n\
3037 {\n\
3038   var hex_tab = hexcase ? \"0123456789ABCDEF\" : \"0123456789abcdef\";\n\
3039   var str = \"\";\n\
3040   for(var i = 0; i < binarray.length * 4; i++)\n\
3041   {\n\
3042     str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +\n\
3043            hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);\n\
3044   }\n\
3045   return str;\n\
3046 }\n\
3047 \n\
3048 /*\n\
3049  * Convert an array of little-endian words to a base-64 string\n\
3050  */\n\
3051 function binl2b64(binarray)\n\
3052 {\n\
3053   var tab = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\
3054   var str = \"\";\n\
3055   for(var i = 0; i < binarray.length * 4; i += 3)\n\
3056   {\n\
3057     var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)\n\
3058                 | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )\n\
3059                 |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);\n\
3060     for(var j = 0; j < 4; j++)\n\
3061     {\n\
3062       if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;\n\
3063       else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);\n\
3064     }\n\
3065   }\n\
3066   return str;\n\
3067 }\n\
3068 \n\
3069 var plainText = \"Rebellious subjects, enemies to peace,\\n\\\n\
3070 Profaners of this neighbour-stained steel,--\\n\\\n\
3071 Will they not hear? What, ho! you men, you beasts,\\n\\\n\
3072 That quench the fire of your pernicious rage\\n\\\n\
3073 With purple fountains issuing from your veins,\\n\\\n\
3074 On pain of torture, from those bloody hands\\n\\\n\
3075 Throw your mistemper'd weapons to the ground,\\n\\\n\
3076 And hear the sentence of your moved prince.\\n\\\n\
3077 Three civil brawls, bred of an airy word,\\n\\\n\
3078 By thee, old Capulet, and Montague,\\n\\\n\
3079 Have thrice disturb'd the quiet of our streets,\\n\\\n\
3080 And made Verona's ancient citizens\\n\\\n\
3081 Cast by their grave beseeming ornaments,\\n\\\n\
3082 To wield old partisans, in hands as old,\\n\\\n\
3083 Canker'd with peace, to part your canker'd hate:\\n\\\n\
3084 If ever you disturb our streets again,\\n\\\n\
3085 Your lives shall pay the forfeit of the peace.\\n\\\n\
3086 For this time, all the rest depart away:\\n\\\n\
3087 You Capulet; shall go along with me:\\n\\\n\
3088 And, Montague, come you this afternoon,\\n\\\n\
3089 To know our further pleasure in this case,\\n\\\n\
3090 To old Free-town, our common judgment-place.\\n\\\n\
3091 Once more, on pain of death, all men depart.\"\n\
3092 \n\
3093 for (var i = 0; i <4; i++) {\n\
3094     plainText += plainText;\n\
3095 }\n\
3096 \n\
3097 var md5Output = hex_md5(plainText);\n\
3098 \n\
3099 var expected = \"a831e91e0f70eddcb70dc61c6f82f6cd\";\n\
3100 \n\
3101 if (md5Output != expected)\n\
3102     throw \"ERROR: bad result: expected \" + expected + \" but got \" + md5Output;\n\
3103 \n\
3104 \n\
3105 \n\
3106 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
3107 \n\
3108 record(_sunSpiderInterval);\n\
3109 </script>\n\
3110 \n\
3111 \n\
3112 </body>\n\
3113 </html>\n\
3114 ", "<!DOCTYPE html>\n\
3115 <head>\n\
3116 \n\
3117 <meta charset=utf8>\n\
3118 \n\
3119 <!--\n\
3120  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
3121 \n\
3122  Redistribution and use in source and binary forms, with or without\n\
3123  modification, are permitted provided that the following conditions\n\
3124  are met:\n\
3125  1. Redistributions of source code must retain the above copyright\n\
3126     notice, this list of conditions and the following disclaimer.\n\
3127  2. Redistributions in binary form must reproduce the above copyright\n\
3128     notice, this list of conditions and the following disclaimer in the\n\
3129     documentation and/or other materials provided with the distribution.\n\
3130 \n\
3131  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
3132  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
3133  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
3134  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
3135  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
3136  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
3137  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
3138  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
3139  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
3140  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
3141  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
3142 -->\n\
3143 \n\
3144 <title>SunSpider crypto-sha1</title>\n\
3145 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
3146 <style>\n\
3147 #countdown {\n\
3148     font-size: 128px; \n\
3149     text-align: center;\n\
3150 }\n\
3151 </style>\n\
3152 </head>\n\
3153 \n\
3154 <body>\n\
3155 <h3 id=\"countdown\"></h3>\n\
3156 <script>\n\
3157 if (window.parent) {\n\
3158     document.getElementById(\"countdown\").innerHTML =\n\
3159         window.parent.currentRepeat < 0\n\
3160             ? \"warmup\"\n\
3161             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
3162 }\n\
3163 \n\
3164 function record(time) {\n\
3165     if (window.parent)\n\
3166         parent.recordResult(time);\n\
3167 }\n\
3168 \n\
3169 window.onerror = function(e) {\n\
3170     console.log(\"crypto-sha1 failed with error: \" + e);\n\
3171     record(0 / 0);\n\
3172 }\n\
3173 \n\
3174 var _sunSpiderStartDate = new Date();\n\
3175 \n\
3176 /*\n\
3177  * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined\n\
3178  * in FIPS PUB 180-1\n\
3179  * Version 2.1a Copyright Paul Johnston 2000 - 2002.\n\
3180  * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n\
3181  * Distributed under the BSD License\n\
3182  * See http://pajhome.org.uk/crypt/md5 for details.\n\
3183  */\n\
3184 \n\
3185 /*\n\
3186  * Configurable variables. You may need to tweak these to be compatible with\n\
3187  * the server-side, but the defaults work in most cases.\n\
3188  */\n\
3189 var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */\n\
3190 var b64pad  = \"\"; /* base-64 pad character. \"=\" for strict RFC compliance   */\n\
3191 var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */\n\
3192 \n\
3193 /*\n\
3194  * These are the functions you'll usually want to call\n\
3195  * They take string arguments and return either hex or base-64 encoded strings\n\
3196  */\n\
3197 function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}\n\
3198 function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}\n\
3199 function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}\n\
3200 function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}\n\
3201 function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}\n\
3202 function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}\n\
3203 \n\
3204 /*\n\
3205  * Perform a simple self-test to see if the VM is working\n\
3206  */\n\
3207 function sha1_vm_test()\n\
3208 {\n\
3209   return hex_sha1(\"abc\") == \"a9993e364706816aba3e25717850c26c9cd0d89d\";\n\
3210 }\n\
3211 \n\
3212 /*\n\
3213  * Calculate the SHA-1 of an array of big-endian words, and a bit length\n\
3214  */\n\
3215 function core_sha1(x, len)\n\
3216 {\n\
3217   /* append padding */\n\
3218   x[len >> 5] |= 0x80 << (24 - len % 32);\n\
3219   x[((len + 64 >> 9) << 4) + 15] = len;\n\
3220 \n\
3221   var w = Array(80);\n\
3222   var a =  1732584193;\n\
3223   var b = -271733879;\n\
3224   var c = -1732584194;\n\
3225   var d =  271733878;\n\
3226   var e = -1009589776;\n\
3227 \n\
3228   for(var i = 0; i < x.length; i += 16)\n\
3229   {\n\
3230     var olda = a;\n\
3231     var oldb = b;\n\
3232     var oldc = c;\n\
3233     var oldd = d;\n\
3234     var olde = e;\n\
3235 \n\
3236     for(var j = 0; j < 80; j++)\n\
3237     {\n\
3238       if(j < 16) w[j] = x[i + j];\n\
3239       else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);\n\
3240       var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),\n\
3241                        safe_add(safe_add(e, w[j]), sha1_kt(j)));\n\
3242       e = d;\n\
3243       d = c;\n\
3244       c = rol(b, 30);\n\
3245       b = a;\n\
3246       a = t;\n\
3247     }\n\
3248 \n\
3249     a = safe_add(a, olda);\n\
3250     b = safe_add(b, oldb);\n\
3251     c = safe_add(c, oldc);\n\
3252     d = safe_add(d, oldd);\n\
3253     e = safe_add(e, olde);\n\
3254   }\n\
3255   return Array(a, b, c, d, e);\n\
3256 \n\
3257 }\n\
3258 \n\
3259 /*\n\
3260  * Perform the appropriate triplet combination function for the current\n\
3261  * iteration\n\
3262  */\n\
3263 function sha1_ft(t, b, c, d)\n\
3264 {\n\
3265   if(t < 20) return (b & c) | ((~b) & d);\n\
3266   if(t < 40) return b ^ c ^ d;\n\
3267   if(t < 60) return (b & c) | (b & d) | (c & d);\n\
3268   return b ^ c ^ d;\n\
3269 }\n\
3270 \n\
3271 /*\n\
3272  * Determine the appropriate additive constant for the current iteration\n\
3273  */\n\
3274 function sha1_kt(t)\n\
3275 {\n\
3276   return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :\n\
3277          (t < 60) ? -1894007588 : -899497514;\n\
3278 }\n\
3279 \n\
3280 /*\n\
3281  * Calculate the HMAC-SHA1 of a key and some data\n\
3282  */\n\
3283 function core_hmac_sha1(key, data)\n\
3284 {\n\
3285   var bkey = str2binb(key);\n\
3286   if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);\n\
3287 \n\
3288   var ipad = Array(16), opad = Array(16);\n\
3289   for(var i = 0; i < 16; i++)\n\
3290   {\n\
3291     ipad[i] = bkey[i] ^ 0x36363636;\n\
3292     opad[i] = bkey[i] ^ 0x5C5C5C5C;\n\
3293   }\n\
3294 \n\
3295   var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);\n\
3296   return core_sha1(opad.concat(hash), 512 + 160);\n\
3297 }\n\
3298 \n\
3299 /*\n\
3300  * Add integers, wrapping at 2^32. This uses 16-bit operations internally\n\
3301  * to work around bugs in some JS interpreters.\n\
3302  */\n\
3303 function safe_add(x, y)\n\
3304 {\n\
3305   var lsw = (x & 0xFFFF) + (y & 0xFFFF);\n\
3306   var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n\
3307   return (msw << 16) | (lsw & 0xFFFF);\n\
3308 }\n\
3309 \n\
3310 /*\n\
3311  * Bitwise rotate a 32-bit number to the left.\n\
3312  */\n\
3313 function rol(num, cnt)\n\
3314 {\n\
3315   return (num << cnt) | (num >>> (32 - cnt));\n\
3316 }\n\
3317 \n\
3318 /*\n\
3319  * Convert an 8-bit or 16-bit string to an array of big-endian words\n\
3320  * In 8-bit function, characters >255 have their hi-byte silently ignored.\n\
3321  */\n\
3322 function str2binb(str)\n\
3323 {\n\
3324   var bin = Array();\n\
3325   var mask = (1 << chrsz) - 1;\n\
3326   for(var i = 0; i < str.length * chrsz; i += chrsz)\n\
3327     bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);\n\
3328   return bin;\n\
3329 }\n\
3330 \n\
3331 /*\n\
3332  * Convert an array of big-endian words to a string\n\
3333  */\n\
3334 function binb2str(bin)\n\
3335 {\n\
3336   var str = \"\";\n\
3337   var mask = (1 << chrsz) - 1;\n\
3338   for(var i = 0; i < bin.length * 32; i += chrsz)\n\
3339     str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);\n\
3340   return str;\n\
3341 }\n\
3342 \n\
3343 /*\n\
3344  * Convert an array of big-endian words to a hex string.\n\
3345  */\n\
3346 function binb2hex(binarray)\n\
3347 {\n\
3348   var hex_tab = hexcase ? \"0123456789ABCDEF\" : \"0123456789abcdef\";\n\
3349   var str = \"\";\n\
3350   for(var i = 0; i < binarray.length * 4; i++)\n\
3351   {\n\
3352     str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +\n\
3353            hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);\n\
3354   }\n\
3355   return str;\n\
3356 }\n\
3357 \n\
3358 /*\n\
3359  * Convert an array of big-endian words to a base-64 string\n\
3360  */\n\
3361 function binb2b64(binarray)\n\
3362 {\n\
3363   var tab = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\
3364   var str = \"\";\n\
3365   for(var i = 0; i < binarray.length * 4; i += 3)\n\
3366   {\n\
3367     var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)\n\
3368                 | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )\n\
3369                 |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);\n\
3370     for(var j = 0; j < 4; j++)\n\
3371     {\n\
3372       if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;\n\
3373       else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);\n\
3374     }\n\
3375   }\n\
3376   return str;\n\
3377 }\n\
3378 \n\
3379 \n\
3380 var plainText = \"Two households, both alike in dignity,\\n\\\n\
3381 In fair Verona, where we lay our scene,\\n\\\n\
3382 From ancient grudge break to new mutiny,\\n\\\n\
3383 Where civil blood makes civil hands unclean.\\n\\\n\
3384 From forth the fatal loins of these two foes\\n\\\n\
3385 A pair of star-cross'd lovers take their life;\\n\\\n\
3386 Whole misadventured piteous overthrows\\n\\\n\
3387 Do with their death bury their parents' strife.\\n\\\n\
3388 The fearful passage of their death-mark'd love,\\n\\\n\
3389 And the continuance of their parents' rage,\\n\\\n\
3390 Which, but their children's end, nought could remove,\\n\\\n\
3391 Is now the two hours' traffic of our stage;\\n\\\n\
3392 The which if you with patient ears attend,\\n\\\n\
3393 What here shall miss, our toil shall strive to mend.\";\n\
3394 \n\
3395 for (var i = 0; i <4; i++) {\n\
3396     plainText += plainText;\n\
3397 }\n\
3398 \n\
3399 var sha1Output = hex_sha1(plainText);\n\
3400 \n\
3401 var expected = \"2524d264def74cce2498bf112bedf00e6c0b796d\";\n\
3402 if (sha1Output != expected)\n\
3403     throw \"ERROR: bad result: expected \" + expected + \" but got \" + sha1Output;\n\
3404 \n\
3405 \n\
3406 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
3407 \n\
3408 record(_sunSpiderInterval);\n\
3409 </script>\n\
3410 \n\
3411 \n\
3412 </body>\n\
3413 </html>\n\
3414 ", "<!DOCTYPE html>\n\
3415 <head>\n\
3416 \n\
3417 <meta charset=utf8>\n\
3418 \n\
3419 <!--\n\
3420  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
3421 \n\
3422  Redistribution and use in source and binary forms, with or without\n\
3423  modification, are permitted provided that the following conditions\n\
3424  are met:\n\
3425  1. Redistributions of source code must retain the above copyright\n\
3426     notice, this list of conditions and the following disclaimer.\n\
3427  2. Redistributions in binary form must reproduce the above copyright\n\
3428     notice, this list of conditions and the following disclaimer in the\n\
3429     documentation and/or other materials provided with the distribution.\n\
3430 \n\
3431  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
3432  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
3433  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
3434  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
3435  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
3436  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
3437  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
3438  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
3439  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
3440  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
3441  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
3442 -->\n\
3443 \n\
3444 <title>SunSpider date-format-tofte</title>\n\
3445 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
3446 <style>\n\
3447 #countdown {\n\
3448     font-size: 128px; \n\
3449     text-align: center;\n\
3450 }\n\
3451 </style>\n\
3452 </head>\n\
3453 \n\
3454 <body>\n\
3455 <h3 id=\"countdown\"></h3>\n\
3456 <script>\n\
3457 if (window.parent) {\n\
3458     document.getElementById(\"countdown\").innerHTML =\n\
3459         window.parent.currentRepeat < 0\n\
3460             ? \"warmup\"\n\
3461             : (window.parent.repeatCount - window.parent.currentRepeat);\n\
3462 }\n\
3463 \n\
3464 function record(time) {\n\
3465     if (window.parent)\n\
3466         parent.recordResult(time);\n\
3467 }\n\
3468 \n\
3469 window.onerror = function(e) {\n\
3470     console.log(\"date-format-tofte failed with error: \" + e);\n\
3471     record(0 / 0);\n\
3472 }\n\
3473 \n\
3474 var _sunSpiderStartDate = new Date();\n\
3475 \n\
3476 function arrayExists(array, x) {\n\
3477     for (var i = 0; i < array.length; i++) {\n\
3478         if (array[i] == x) return true;\n\
3479     }\n\
3480     return false;\n\
3481 }\n\
3482 \n\
3483 Date.prototype.formatDate = function (input,time) {\n\
3484     // formatDate :\n\
3485     // a PHP date like function, for formatting date strings\n\
3486     // See: http://www.php.net/date\n\
3487     //\n\
3488     // input : format string\n\
3489     // time : epoch time (seconds, and optional)\n\
3490     //\n\
3491     // if time is not passed, formatting is based on \n\
3492     // the current \"this\" date object's set time.\n\
3493     //\n\
3494     // supported:\n\
3495     // a, A, B, d, D, F, g, G, h, H, i, j, l (lowercase L), L, \n\
3496     // m, M, n, O, r, s, S, t, U, w, W, y, Y, z\n\
3497     //\n\
3498     // unsupported:\n\
3499     // I (capital i), T, Z    \n\
3500 \n\
3501     var switches =    [\"a\", \"A\", \"B\", \"d\", \"D\", \"F\", \"g\", \"G\", \"h\", \"H\", \n\
3502                        \"i\", \"j\", \"l\", \"L\", \"m\", \"M\", \"n\", \"O\", \"r\", \"s\", \n\
3503                        \"S\", \"t\", \"U\", \"w\", \"W\", \"y\", \"Y\", \"z\"];\n\
3504     var daysLong =    [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \n\
3505                        \"Thursday\", \"Friday\", \"Saturday\"];\n\
3506     var daysShort =   [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \n\
3507                        \"Thu\", \"Fri\", \"Sat\"];\n\
3508     var monthsShort = [\"Jan\", \"Feb\", \"Mar\", \"Apr\",\n\
3509                        \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\",\n\
3510                        \"Oct\", \"Nov\", \"Dec\"];\n\
3511     var monthsLong =  [\"January\", \"February\", \"March\", \"April\",\n\
3512                        \"May\", \"June\", \"July\", \"August\", \"September\",\n\
3513                        \"October\", \"November\", \"December\"];\n\
3514     var daysSuffix = [\"st\", \"nd\", \"rd\", \"th\", \"th\", \"th\", \"th\", // 1st - 7th\n\
3515                       \"th\", \"th\", \"th\", \"th\", \"th\", \"th\", \"th\", // 8th - 14th\n\
3516                       \"th\", \"th\", \"th\", \"th\", \"th\", \"th\", \"st\", // 15th - 21st\n\
3517                       \"nd\", \"rd\", \"th\", \"th\", \"th\", \"th\", \"th\", // 22nd - 28th\n\
3518                       \"th\", \"th\", \"st\"];                        // 29th - 31st\n\
3519 \n\
3520     function a() {\n\
3521         // Lowercase Ante meridiem and Post meridiem\n\
3522         return self.getHours() > 11? \"pm\" : \"am\";\n\
3523     }\n\
3524     function A() {\n\
3525         // Uppercase Ante meridiem and Post meridiem\n\
3526         return self.getHours() > 11? \"PM\" : \"AM\";\n\
3527     }\n\
3528 \n\